ImportError:没有名为_ctypes的模块.谷歌应用程序引擎与散景图

jog*_*oga 8 python google-app-engine ctypes bokeh

  • Python 2.7.13
  • Windows 10 64位

我一直在研究这个Udacity web dev课程,并想尝试使用这个例子将简单的散景图嵌入到网页中.运行dev_appserver.py给出错误:ImportError: No module named _ctypes

我有:

  • 安装散景和Numpy通过点子
  • 在app.yaml中包含Numpy

这个答案表明Google App Engine不允许导入ctypes.但是我不确定如何确认Bokeh是否属于这种情况.这是由Bokeh导入ctypes引起的错误吗?如果有的话有解决方法吗?

ERROR    2017-01-21 19:14:53,799 wsgi.py:263]
Traceback (most recent call last):
  File "C:\Users\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform
\google_appengine\google\appengine\runtime\wsgi.py", line 240, in Handle
    handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
  File "C:\Users\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform
\google_appengine\google\appengine\runtime\wsgi.py", line 299, in _LoadHandler
    handler, path, err = LoadObject(self._handler)
  File "C:\Users\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform
\google_appengine\google\appengine\runtime\wsgi.py", line 85, in LoadObject
    obj = __import__(path[0])
  File "C:\Users\Google Drive\Udacity web development 2017\udacit
y-cs253\bokeh\1_docs_example\main.py", line 2, in <module>
    from bokeh.plotting import figure
  File "C:\Users\Google Drive\Udacity web development 2017\udacit
y-cs253\bokeh\1_docs_example\lib\bokeh\plotting\__init__.py", line 2, in <module
>
    from ..document import Document; Document
  File "C:\Users\Google Drive\Udacity web development 2017\udacit
y-cs253\bokeh\1_docs_example\lib\bokeh\document.py", line 45, in <module>
    from .core.json_encoder import serialize_json
  File "C:\Users\Google Drive\Udacity web development 2017\udacit
y-cs253\bokeh\1_docs_example\lib\bokeh\core\json_encoder.py", line 43, in <modul
e>
    import numpy as np
  File "C:\Users\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform
\google_appengine\google\appengine\tools\devappserver2\python\sandbox.py", line
706, in load_module
    module = self._find_and_load_module(fullname, fullname, [module_path])
  File "C:\Users\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform
\google_appengine\google\appengine\tools\devappserver2\python\sandbox.py", line
447, in _find_and_load_module
    return imp.load_module(fullname, source_file, path_name, description)
  File "D:\Python27\lib\numpy\__init__.py", line 142, in <module>
    from . import add_newdocs
INFO     2017-01-21 19:14:53,859 module.py:806] default: "GET / HTTP/1.1" 500 -
  File "D:\Python27\lib\numpy\add_newdocs.py", line 13, in <module>
    from numpy.lib import add_newdoc
  File "D:\Python27\lib\numpy\lib\__init__.py", line 8, in <module>
    from .type_check import *
  File "D:\Python27\lib\numpy\lib\type_check.py", line 11, in <module>
    import numpy.core.numeric as _nx
  File "D:\Python27\lib\numpy\core\__init__.py", line 33, in <module>
    from . import _internal  # for freeze programs
  File "D:\Python27\lib\numpy\core\_internal.py", line 14, in <module>
    import ctypes
  File "D:\Python27\lib\ctypes\__init__.py", line 7, in <module>
    from _ctypes import Union, Structure, Array
  File "C:\Users\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform
\google_appengine\google\appengine\tools\devappserver2\python\sandbox.py", line
964, in load_module
    raise ImportError('No module named %s' % fullname)
ImportError: No module named _ctypes
Run Code Online (Sandbox Code Playgroud)

app.yaml中:

runtime: python27
api_version: 1
threadsafe: true

handlers:
- url: /.*
  script: main.app

libraries:
- name: jinja2
  version: latest
- name: numpy
  version: latest
Run Code Online (Sandbox Code Playgroud)

main.py

import os, webapp2, jinja2
from bokeh.plotting import figure
from bokeh.embed import components

plot = figure()
plot.circle([1,2], [3,4])
script, div = components(plot)

template_dir = os.path.join(os.path.dirname(__file__), 'templates')
jinja_env = jinja2.Environment(loader = jinja2.FileSystemLoader(template_dir),
                                autoescape = True)

class Handler(webapp2.RequestHandler):
    def write(self, *a, **kw):
        self.response.write(*a, **kw)

    def render_str(self, template, **kw):
        t = jinja_env.get_template(template)
        return t.render(kw)

    def render(self, template, **kw):
        self.write(self.render_str(template, **kw))

class MainPage(Handler):
    def get(self):
        self.render("chart.html", script = script, div = div)

app = webapp2.WSGIApplication([
    ('/', MainPage),
], debug=True)
Run Code Online (Sandbox Code Playgroud)

chart.html

{% extends "base.html" %}

{% block content %}

<!-- Load BokehJS -->
<link
    href="http://cdn.bokeh.org/bokeh/release/bokeh-0.12.0.min.css"
    rel="stylesheet" type="text/css">
<link
    href="http://cdn.bokeh.org/bokeh/release/bokeh-widgets-0.12.0.min.css"
    rel="stylesheet" type="text/css">

<script src="http://cdn.bokeh.org/bokeh/release/bokeh-0.12.0.min.js"></script>
<script src="http://cdn.bokeh.org/bokeh/release/bokeh-widgets-0.12.0.min.js"></script>

{{ script }}
{{ div }}

{% endblock %}
Run Code Online (Sandbox Code Playgroud)

base.html文件

<!DOCTYPE html>
<html>
<head>
    <title>Udacity Templates!</title>
</head>
<body style="margin: 0">
    <h1 style="background-color: #ddd; color: #888; margin: 0; height: 50px">Udacity Templates</h1>
    {% block content %}
    {% endblock %}
</body>
</html>
Run Code Online (Sandbox Code Playgroud)

gcloud版本

  • Google Cloud SDK 139.0.1
  • app-engine-python 1.9.49
  • bq 2.0.24
  • bq-win 2.0.24
  • bundled-python 2.7.10
  • 核心2017.01.12
  • 核心胜利2016.11.07
  • gcloud
  • gsutil 4.22
  • gsutil-win 4.20
  • powershell 1.0.0.1
  • windows-ssh-tools 2016.05.13

更新1: 我已经卸载了numpy 1.12.0并安装了numpy 1.6.1.我现在得到这个错误:

NP_MS_DELTA = np.timedelta64(1, 'ms')
TypeError: function takes at most 1 argument (2 given)
Run Code Online (Sandbox Code Playgroud)

表示numpy 1.6.1无法在标量构造函数中指定单位.这是否意味着Bokeh依赖于numpy> 1.6.1?

ERROR    2017-01-22 10:37:45,980 wsgi.py:263]
Traceback (most recent call last):
  File "C:\Users\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform
\google_appengine\google\appengine\runtime\wsgi.py", line 240, in Handle
    handler = _config_handle.add_wsgi_middleware(self._LoadHandler())
  File "C:\Users\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform
\google_appengine\google\appengine\runtime\wsgi.py", line 299, in _LoadHandler
    handler, path, err = LoadObject(self._handler)
  File "C:\Users\AppData\Local\Google\Cloud SDK\google-cloud-sdk\platform
\google_appengine\google\appengine\runtime\wsgi.py", line 85, in LoadObject
    obj = __import__(path[0])
  File "C:\Users\Google Drive\Udacity web development 2017\udacit
y-cs253\bokeh\1_docs_example\main.py", line 2, in <module>
    from bokeh.plotting import figure
  File "C:\Users\Google Drive\Udacity web development 2017\udacit
y-cs253\bokeh\1_docs_example\lib\bokeh\plotting\__init__.py", line 2, in <module
>
    from ..document import Document; Document
  File "C:\Users\Google Drive\Udacity web development 2017\udacit
y-cs253\bokeh\1_docs_example\lib\bokeh\document.py", line 45, in <module>
    from .core.json_encoder import serialize_json
  File "C:\Users\Google Drive\Udacity web development 2017\udacit
y-cs253\bokeh\1_docs_example\lib\bokeh\core\json_encoder.py", line 53, in <modul
e>
    NP_MS_DELTA = np.timedelta64(1, 'ms')
TypeError: function takes at most 1 argument (2 given)
INFO     2017-01-22 10:37:46,170 module.py:806] default: "GET / HTTP/1.1" 500 -
Run Code Online (Sandbox Code Playgroud)

更新2:

这让我想起了当我点了装Bokeh的时候.当下载它的依赖性numpy时,它似乎依赖于numpy> = 1.7.1:

Collecting numpy>=1.7.1 (from Bokeh)
Run Code Online (Sandbox Code Playgroud)

小智 8

我设法使用2个黑客运行开发服务器

ImportError: No module named _ctypes
Run Code Online (Sandbox Code Playgroud)

这实际上是由烧瓶引起的New Flask使用名为click的库,它使用ctypes Gae不允许ctypes解决方案:安装和旧版本的click

pip install --target lib --upgrade click==5.1
Run Code Online (Sandbox Code Playgroud)

这修复了ctypes但导致另一个错误

ImportError: No module named msvcrt
Run Code Online (Sandbox Code Playgroud)

通过将这些行添加到appengine_config.py(位于与app.yaml相同的文件夹中)可以轻松修复此问题.

import os, sys

on_appengine = os.environ.get('SERVER_SOFTWARE','').startswith('Development')
if on_appengine and os.name == 'nt':
    sys.platform = "Not Windows"
Run Code Online (Sandbox Code Playgroud)

这个开发服务器启动并运行后


小智 5

谷歌发布的解决方法:

https://issuetracker.google.com/issues/38290292

  • <sdk_root>\google\appengine\tools\devappserver2\python\sandbox.py
  • 找到_WHITE_LIST_C_MODULES = [xxx]
    以下两行添加到列表中的定义 :

    '_winreg',
    '_ctypes',
    
    Run Code Online (Sandbox Code Playgroud)
  • 再试一次你的应用.

为我工作.

  • 添加这两行后,我的`msvcrt`出现了类似的错误.将`msvcrt`添加到`_WHITE_LIST_C_MODULES`列表修复了该错误. (2认同)

big*_*dot 2

编辑:请参阅下面的答案,了解 Google 的新解决方法。


我可以明确地说,Bokeh 本身并不ctypes直接在库中的任何地方使用。但它确实使用了 NumPy,而且似乎至少某些版本的 NumPy 确实使用了ctypes? 这个链接:

http://kawahara.ca/using-numpy-on-google-app-engine-with-the-anaconda-python-distribution/

似乎表明GAE支持 NumPy 1.6 版本。我可能会认为这是因为该版本不使用ctypes,或者因为 Google 已以某种方式将该版本明确列入白名单为可接受的。

因此建议专门安装 NumPy 1.6,而不是最新版本(使用 pip 或 conda 或其他)。