【问题标题】:"ImportError: No module named _ssl" with dev_appserver.py from Google App Engine来自 Google App Engine 的带有 dev_appserver.py 的“ImportError:没有名为 _ssl 的模块”
【发布时间】:2013-04-18 01:24:39
【问题描述】:

背景

“在 Python 运行时,我们添加了对 Python SSL 的支持 库,因此您现在可以打开与远程服务的安全连接 例如 Apple 的推送通知服务。”

此报价为taken from a recent post on the Google App Engine blog


实施

如果您想使用本机 python ssl,您必须使用应用程序 app.yaml 文件中的库配置启用它,在该文件中您指定库名称“ssl”。 . .

这些说明通过Google App Engine documentation 提供给开发人员。

以下行已添加到app.yaml 文件中:

libraries:
- name: ssl
  version: latest

这与通过 Google App Engine 文档提供的建议一致。


问题

我尝试过以三种不同的配置运行我的项目。两个在工作,一个没有。

工作...

在我将应用程序上传到 Google App Engine 并通过实时服务器运行我的项目后,一切正常。

工作...

当我使用manage.py runserver 运行我的项目并将Google App Engine SKD 包含在我的PYTHONPATH 中时,一切正常。

不工作...

但是,当我使用 dev_appserver.py 运行我的项目时,我收到以下错误:

ImportError at /
No module named _ssl
Request Method: GET
Request URL:    http://localhost:8080/
Django Version: 1.4.3
Exception Type: ImportError
Exception Value:    
No module named _ssl
Exception Location: /usr/local/lib/google_appengine_1.7.7/google/appengine/tools/devappserver2/python/sandbox.py in load_module, line 856
Python Executable:  /home/rbose85/Code/venvs/appserver/bin/python
Python Version: 2.7.3
Python Path:    
['/home/rbose85/Code/product/site',
 '/usr/local/lib/google_appengine_1.7.7',
 '/usr/local/lib/google_appengine_1.7.7/lib/protorpc',
 '/usr/local/lib/google_appengine_1.7.7',
 '/usr/local/lib/google_appengine_1.7.7',
 '/usr/local/lib/google_appengine_1.7.7/lib/protorpc',
 '/usr/local/lib/google_appengine_1.7.7',
 '/usr/local/lib/google_appengine_1.7.7/lib/protorpc',
 '/home/rbose85/Code/venvs/appserver/lib/python2.7',
 '/home/rbose85/Code/venvs/appserver/lib/python2.7/lib-dynload',
 '/usr/lib/python2.7',
 '/usr/local/lib/google_appengine',
 u'/usr/local/lib/google_appengine_1.7.7/lib/django-1.4',
 u'/usr/local/lib/google_appengine_1.7.7/lib/ssl-2.7',
 u'/usr/local/lib/google_appengine_1.7.7/lib/webapp2-2.3',
 u'/usr/local/lib/google_appengine_1.7.7/lib/webob-1.1.1',
 u'/usr/local/lib/google_appengine_1.7.7/lib/yaml-3.10']
Server time:    Wed, 24 Apr 2013 11:23:49 +0000

【问题讨论】:

    标签: google-app-engine openssl


    【解决方案1】:

    对于当前的 GAE 版本(1.8.0 至少到 1.8.3),如果您希望能够在您的开发环境中调试 SSL 连接,您需要稍微调整一下 gae 沙箱:

    • 在 /path-to-gae-sdk/google/appengine/tools/devappserver2/python/sandbox.py 中的字典 _WHITE_LIST_C_MODULES 中添加“_ssl”和“_socket”键
    • 从 Python 框架的 socket.py 文件中替换 /path-to-gae-sdk/google/appengine/dis27 中 google 提供的 socket.py 文件。

    重要提示:调整沙盒环境可能会导致功能在您的本地机器上运行,但在生产中不可用(例如,GAE 仅支持生产中的出站套接字)。我会建议您在开发完应用程序的特定部分后恢复您的沙盒。

    【讨论】:

    • 此修复适用于阻塞 (ssl) 套接字,但不适用于非阻塞套接字。 GAE(和开发服务器)也包装了选择模块,该模块仅适用于 GAE 套接字对象。使用内置套接字执行 select() 会引发异常。我试图让开发服务器使用内置的选择模块位,但没有找到办法。有什么建议吗?
    • 对于那些(像我一样)不知道在哪里可以找到path-to-gae 的人来说,请注意。在您的终端中运行:ls -l `which dev_appserver.py` 这将向您显示真实路径。在google_appengine 目录上执行cd,然后cd google/appengine/tools/devappserver2/python/
    • 实际上对我来说,从 Google App Engine 主目录中,您 cd 进入 google/appengine/dist27 并且 socket.py 就在那里......正如 jmg 在他的回答中所说的那样。
    • 这个 hack 可能会欺骗 sdk,但会导致生产错误(至少在我的情况下)
    • 当我替换文件 socket.py 文件文件“/opt/google_appengine/google/appengine/tools/devappserver2/python/sandbox.py”,第 950 行,在 load_module raise ImportError( 'No module named %s' % fullname) ImportError: No module named _socket 有什么解决办法吗?我只找到了 Windows 答案。
    【解决方案2】:

    jmg 的解决方案有效,但您可以修改相关模块,而不是更改 sdk 文件。

    只需在项目设置的开头添加这样的内容即可。

    # Just taking flask as an example
    app = Flask('myapp')
    
    if environment == 'DEV':
        import sys
    
        from google.appengine.tools.devappserver2.python import sandbox
        sandbox._WHITE_LIST_C_MODULES += ['_ssl', '_socket']
    
        from lib import copy_of_stdlib_socket.py as patched_socket
    
        sys.modules['socket'] = patched_socket
        socket = patched_socket
    

    【讨论】:

    • +1 仅用于代码解决方案,无需使用 appengine 文件。
    • 如果你到了这里并使用了这个解决方案,你就会遇到关于非阻塞套接字的问题(以及使用select)。将这两行添加到修复程序中,在import sys 正下方将完全禁用非阻塞套接字:import select 然后del sys.modules['select'].select
    • from lib import copy_of_stdlib_socket.py as patched_socket 这行是关于什么的? PyCharm 说“找不到模块。”
    • 对于那些想知道copy_of_stdlib_socket.py的人来说,这个想法是将Python核心socket.py文件复制到项目目录树中的一个新文件中,名称类似于copy_of_stdlib_socket.py,然后导入该文件.有一些东西覆盖了默认的套接字模块,我们想把它覆盖回来。
    • 您甚至无需将socket.py 复制到新文件即可完成此操作,根据此答案:stackoverflow.com/a/36272309/1464495
    【解决方案3】:

    我不得不使用稍微不同的方法来让它在 CircleCI 中工作(不确定他们的 venv 配置的特殊性导致了这个):

    appengine_config.py

    import os
    
    if os.environ.get('SERVER_SOFTWARE', '').startswith('Development'):
        import imp
        import os.path
        import inspect
        from google.appengine.tools.devappserver2.python import sandbox
    
        sandbox._WHITE_LIST_C_MODULES += ['_ssl', '_socket']
        # Use the system socket.
    
        real_os_src_path = os.path.realpath(inspect.getsourcefile(os))
        psocket = os.path.join(os.path.dirname(real_os_src_path), 'socket.py')
        imp.load_source('socket', psocket)
    

    【讨论】:

    • 这个答案似乎是最安全的路线,应该标记出来。我要补充一点,它应该放在你的基本应用目录中一个名为 appengine_config.py 的文件中,以便在启动时加载它。
    • 第 737 行,在 HTTPConnection 中我得到 timeout=socket._GLOBAL_DEFAULT_TIMEOUT, source_address=None): AttributeError: 'module' object has no attribute '_GLOBAL_DEFAULT_TIMEOUT'
    • 看起来是一个完美的解决方案,但在我的情况下,我使用的是 virtualenv,它无法在手动下载和放置 socket.py 时找到 socket.py,它给出了一个错误提示 [Errno 22] Invalid论据.
    • @vinitpayal 不幸的是,GAE 不适用于 venv。卖货是最好的方式 - cloud.google.com/appengine/docs/standard/python/tools/…
    • @SpainTrain 感谢您在投入大量时间后的回复,我能够在 venv 上完成这项工作。我认为有效的是stackoverflow.com/questions/33822937/…
    【解决方案4】:

    我遇到了这个问题,因为我没有在 app.yaml 文件中提供 ssl。我知道 OP 是这样做的,但是对于那些因 OP 的错误而登陆这里的人,值得确保您的 app.yaml 文件中有如下行:

    libraries:
    - name: ssl
      version: latest
    

    【讨论】:

    • 说真的。 GAE 最初是他们的旗舰 PaaS,在向 3.7 的过渡中,他们一直将其视为一个副项目(即几乎没有 3.7 的本地开发工具,在进行更改时不更新 2.7 文档,不迁移内置库(即 NDB)到 3.7 等)。随着 Python 2.7 的日落,希望 2019 年剩下的时间在这里有所改善。
    【解决方案5】:

    偶然发现这个线程试图与 Apples Push 通知服务和 appengine 一起工作...我能够通过在我的 app.yaml 中添加 SSL 库,在没有任何猴子补丁的情况下完成这个工作,正如 official docs 中所推荐的那样,希望对其他人有所帮助:)

    【讨论】:

      【解决方案6】:

      我将代码添加到西班牙火车列出的 appengine_config.py 中,但还必须添加以下代码才能使其正常工作:

      phttplib = os.path.join(os.path.dirname(real_os_src_path), 'httplib.py')
      imp.load_source('httplib', phttplib)
      

      【讨论】:

        【解决方案7】:

        您可以通过打开 python shell 并输入 import ssl 来测试本地系统是否可以使用 ssl。如果没有出现错误,则问题出在其他问题上,否则您的系统上没有安装相关库。如果您使用的是 Linux 操作系统,请尝试使用sudo apt-get install openssl openssl-devel 或您的操作系统的相关说明在本地安装它们。如果您使用的是 Windows,这些是 instructions

        【讨论】:

        • 感谢您的回答。非常好的信息,但不是我需要的。我同意你的观点,如果我打开 Python shell 并输入import ssl,我可以非常快速地测试 SSL 模块是否可用于我的环境。但是,我并没有尝试在本地 Python 上使用 SSL。 我遇到的问题是在 Google App Engine 中使用 SSL。我可以通过 Django 的manage.py runserver 毫无问题地运行我的项目。问题是通过 AppEngine 的dev_appserver.py 运行我的项目时。当我使用dev_appserver.py 时,我遇到了上述问题。
        • 您的问题有什么解决方案吗?也遇到了。
        • 我不知道,我认为这是一个更广泛的系统安装问题。
        猜你喜欢
        • 2011-07-04
        • 2015-01-25
        • 2019-05-24
        • 1970-01-01
        • 2017-11-12
        • 2013-03-06
        • 2014-10-30
        • 1970-01-01
        相关资源
        最近更新 更多