ImportError:不允许从用户应用程序代码导入devappserver沙箱模块

pma*_*old 6 python google-app-engine

我正在开发一个用Python(标准环境)编写的Google App Engine应用程序,我需要在开发服务器环境中将一些其他模块列入白名单.

我一直在appengine_config文件中使用这段代码做了很长时间,并且效果非常好:

from google.appengine.tools.devappserver2.python import sandbox
sandbox._WHITE_LIST_C_MODULES += ['_ssl', '_socket']
Run Code Online (Sandbox Code Playgroud)

正如在这个问题中所回答的,前一段时间Google Cloud SDK已更新,之前的导入导致了ImportError.导入只需要更改为:

from google.appengine.tools.devappserver2.python.runtime import sandbox
Run Code Online (Sandbox Code Playgroud)

通过此更改,一切都运行良好,直到我将Cloud SDK更新为版本:186.0.0.

现在看来沙盒模块中添加了"SandboxAccessPreventionImportHook"类,因此无法从App Engine应用程序导入.这是应用程序引发的错误:

ImportError: Importing the devappserver sandbox module (google.appengine.tools.devappserver2.python.runtime.sandbox) from user application code is not permitted.
Run Code Online (Sandbox Code Playgroud)

有没有人知道如何绕过这个?或者是否有另一种方法将开发服务器环境中的模块列入白名单?

谢谢!!!

Ale*_*lex 1

语境

所以对我来说这个问题的根源是dev_appserver.py无法发送出站 https 请求/套接字。

然后的解决方案是将其放入我的appengine_config.py

vendor.add('lib')

if os.environ.get('SERVER_SOFTWARE', '').startswith('Development'):
    import imp
    import os.path
    import inspect
    try:
        from google.appengine.tools.devappserver2.python import sandbox
    except ImportError:
        from google.appengine.tools.devappserver2.python.runtime 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)
else:
    # Doing this on dev_appserver/localhost seems to cause outbound https requests to fail
    import requests
    from requests_toolbelt.adapters import appengine as requests_toolbelt_appengine

    # Use the App Engine Requests adapter. This makes sure that Requests uses
    # URLFetch.
    requests_toolbelt_appengine.monkeypatch() 
Run Code Online (Sandbox Code Playgroud)

今天我升级了我的云sdk并开始获取

ImportError: Importing the devappserver sandbox module (google.appengine.tools.devappserver2.python.runtime.sandbox) from user application code is not permitted.
Run Code Online (Sandbox Code Playgroud)

如果我删除这些_WHITE_LIST_C_MODULES内容,那么当使用 python requests 库发出出站 https 请求时,我会收到此错误:

  File "/Users/alexindaco/google-cloud-sdk/platform/google_appengine/google/appengine/api/urlfetch.py", line 293, in fetch
    return rpc.get_result()
  File "/Users/alexindaco/google-cloud-sdk/platform/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 613, in get_result
    return self.__get_result_hook(self)
  File "/Users/alexindaco/google-cloud-sdk/platform/google_appengine/google/appengine/api/urlfetch.py", line 413, in _get_fetch_result
    rpc.check_success()
  File "/Users/alexindaco/google-cloud-sdk/platform/google_appengine/google/appengine/api/apiproxy_stub_map.py", line 579, in check_success
    self.__rpc.CheckSuccess()
  File "/Users/alexindaco/google-cloud-sdk/platform/google_appengine/google/appengine/api/apiproxy_rpc.py", line 157, in _WaitImpl
    self.request, self.response)
  File "/Users/alexindaco/google-cloud-sdk/platform/google_appengine/google/appengine/ext/remote_api/remote_api_stub.py", line 222, in MakeSyncCall
    self._MakeRealSyncCall(service, call, request, response)
  File "/Users/alexindaco/google-cloud-sdk/platform/google_appengine/google/appengine/ext/remote_api/remote_api_stub.py", line 241, in _MakeRealSyncCall
    request_pb.set_request(request.Encode())
  File "/Users/alexindaco/google-cloud-sdk/platform/google_appengine/google/net/proto/ProtocolBuffer.py", line 103, in Encode
    self.Output(e)
  File "/Users/alexindaco/google-cloud-sdk/platform/google_appengine/google/net/proto/ProtocolBuffer.py", line 347, in Output
    self.OutputUnchecked(e)
  File "/Users/alexindaco/google-cloud-sdk/platform/google_appengine/google/appengine/api/urlfetch_service_pb.py", line 481, in OutputUnchecked
    out.putDouble(self.deadline_)
  File "/Users/alexindaco/google-cloud-sdk/platform/google_appengine/google/net/proto/ProtocolBuffer.py", line 592, in putDouble
    a.fromstring(struct.pack("<d", v))
error: required argument is not a float 
Run Code Online (Sandbox Code Playgroud)

然后我发现这个问题中的堆栈跟踪 https://github.com/requests/requests/issues/4078 这似乎表明这只是在 python-requests 版本 2.16.0 之后才开始发生

解决方案

我的所有第三方库都安装到项目根目录中名为libusing的文件夹中

pip install -t lib
Run Code Online (Sandbox Code Playgroud)

现在,我已经lib&localhost_libs并且我做了:

pip install -t localhost_libs requests==2.16
Run Code Online (Sandbox Code Playgroud)

我的 appengine_config.py 现在有这个:

vendor.add('lib')

if os.environ.get('SERVER_SOFTWARE', '').startswith('Development'):
    vendor.add('localhost_libs')
    import pkg_resources
    pkg_resources.require("requests==2.16.0")
import requests
print "requests.__version__", requests.__version__

from requests_toolbelt.adapters import appengine as requests_toolbelt_appengine

# Use the App Engine Requests adapter. This makes sure that Requests uses
# URLFetch.
requests_toolbelt_appengine.monkeypatch()
print "Appengine config done"
Run Code Online (Sandbox Code Playgroud)

编辑:修改解决方案以使用pkg_resources且不需要prod_libs文件夹