Python Requests库能在Google App Engine上使用吗?

34

我能在Google App Engine上使用Requests库吗?我认为这个库非常适合创建REST客户端。

7个回答

43
安装requests-toolbelt库: https://github.com/sigmavirus24/requests-toolbelt 对于App Engine,可以使用以下命令: pip install requests-toolbelt -t lib
(参见:https://cloud.google.com/appengine/docs/python/tools/using-libraries-python-27#installing_a_library
然后添加:
from requests_toolbelt.adapters import appengine
appengine.monkeypatch()

在你的 main.py 文件或相应文件中。
编辑:这个解决方案现在已经成为官方文档的一部分:https://cloud.google.com/appengine/docs/python/issue-requests#issuing_an_http_request(在 REQUESTS 标签下)。

2
请注意,appengine.monkeypatch() 行应该在您导入使用 requests 的任何模块之前导入。 - J Wang
这应该是被接受的答案,它对我起作用了。 - Diab
虽然这适用于大多数情况,但应该注意到这种方法使用App Engine的 urlfetch,它在免费配额下可用但具有一些限制。例如,它当前不支持客户端证书,而这与目前接受的答案中所使用的套接字有关的方法相反。 - David Pärsson

27
是的,在Google Appengine (版本1.9.18)上,如果您开启了计费功能以启用套接字支持,那么requests版本2.3.0可以在生产环境中使用(但无法在SDK中使用)。
更新:截至2017年1月31日,requests 2.9.1版本已在生产环境中正常工作。然而,在 Google Cloud SDK 141.0.0上无法正常工作。
在Appengine SDK上,所有https://请求都会导致requests失败:
  ConnectionError: ('Connection aborted.', error(13, 'Permission denied'))

requests 2.4.1在生产中出现以下问题:

  File "distlib/requests/adapters.py", line 407, in send
    raise ConnectionError(err, request=request)
  ConnectionError: ('Connection aborted.', error(13, 'Permission denied'))

requests版本2.5.1在生产环境中出现故障:

  File "distlib/requests/adapters.py", line 415, in send
    raise ConnectionError(err, request=request)
  ConnectionError: ('Connection aborted.', error(13, 'Permission denied'))

请求库版本2.3.0可以在生产环境中使用,但可能会在Debian SDK删除了SSLv3支持后出现问题(requests 2.3.0附带了已过时的urllib3)。作为解决方法,可以在请求库urllib3副本的源代码中删除包含PROTOCOL_SSLv3的行。

  'module' object has no attribute 'PROTOCOL_SSLv3'

有关套接字支持的信息:https://cloud.google.com/appengine/docs/python/sockets/


3
你可以通过加载 SSL 库来简单修复 https:// 请求,具体方法见 https://dev59.com/EF0a5IYBdhLWcg3wYn52#34135758。 - Yahel
请求一个HTTPS网站可以正常工作,即使我没有启用计费 - 这是为什么? - Kevin Lee
我刚刚发现,只要请求库没有实际使用套接字库,如果计费未启用(即未使用的导入和未使用的代码),App Engine将不会抛出异常。这是因为我只进行了简单的GET请求。在检查我的配额使用情况时,实际上调用的是App Engine的URL获取库(在我的用例中,使用urllib2而不是requests可能是更好的选择)。此外,对于我的情况,它可以在不包括SSL库的情况下工作;App Engine的URL获取支持https。 - Kevin Lee
在实际服务器上加载ssl库可作为修复措施,但在开发服务器上不行,似乎。 - user2738183
将请求更改为版本2.3.0并在app.yml中包含“ssl”库,问题得到了解决!谢谢。 - kornesh
2.6 版怎么样? - Andrew Stromme

8

现在可以做到了,我使用appengine_config.py中的以下解决方案组合使它起作用:

# Step 1: first add requests and requests-toolbelt to your requirements.txt (or however you install them via pip)
# Step 2: in appengine_config.py add the following snippet:

# see https://cloud.google.com/appengine/docs/python/issue-requests#issuing_an_http_request
import requests
import requests_toolbelt.adapters.appengine

# Use the App Engine Requests adapter. This makes sure that Requests uses
# URLFetch.
requests_toolbelt.adapters.appengine.monkeypatch()

# also monkey patch platform.platform() from https://code.google.com/p/googleappengine/issues/detail?id=12982
import platform

def patch(module):
    def decorate(func):
        setattr(module, func.func_name, func)
        return func
    return decorate


@patch(platform)
def platform():
    return 'AppEngine'

谢谢,除了 def platform() 不需要缩进。 - vkb
目前来看,这应该是被接受的答案,因为谷歌并没有将此写入他们的文档中。requests_toolbelt monkey patch 可以正常工作。 - Ian Zhao

8
目前还没有,但希望很快会有支持。正在处理对GAE的支持 - 请参见问题#498(App Engine Fixes)。
Requests使用urllib3,而urllib3又使用httplib,它是作为urlfetch API的包装器在GAE上得到支持的。虽然urllib3使用了一些在GAE上不可用的模块,但这种使用被故意地设为可选项,以便urllib3可以在GAE上使用。

你知道这个是否已经改变了吗? - clifgray
我不知道,但你可以在问题中询问答案。 - Piotr Dobrogost
1
你是怎么让它工作的?即使晚了,知道如何做也是好的。 - EsseTi

3
不,根据最近的一篇文章,开发者表示他们不支持GAE因为它和Python有很大的区别。

他们不支持它,但你仍然可以使用该库。只需下载源代码并直接导入即可。如果需要使用套接字来绕过 urlfetch() 限制,请使用 sockets - user3058197
你启用了套接字吗? - user3058197
抱歉,@Ann,我忘记了需要对请求源进行一些调整,以使其与App Engine兼容。尝试使用这个链接,我认为应该可以解决问题。如果你遇到问题并想使用Requests,请告诉我,我可以发布我使用的可行源代码...让我知道吧。 - user3058197

2
为了让我的应用程序能够在Google App Engine上正常运行,同时也能够在GAE之外运行,我添加了以下代码:
try:
    from google.appengine.api import urlfetch
    from requests_toolbelt.adapters import appengine
    appengine.monkeypatch()
except ImportError:
    pass

0

是的,您可以使用requests模块。 GCP默认不支持使用Requests库。因此,我们需要进行一些调整才能使其正常工作。 为了在Google App Engine上部署应用程序,我们需要创建一个main.py(包含主Python Flask应用程序)和一个app.yaml(运行所需的配置文件)。 以下是Python 2.7环境下app.yaml文件的示例代码:

runtime: python27
api_version: 1
threadsafe: true

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

libraries:
- name: flask
  version: 0.12

现在我们需要配置请求库以在内部使用URLfetch。 为了使用requests,我们需要按照供应商指南安装requests和requests-toolbelt。(https://cloud.google.com/appengine/docs/standard/python/tools/using-libraries-python-27#installing_a_library)。 基本上,我们需要安装自定义库。

  1. 创建一个目录来存储第三方库,例如lib/ mkdir lib
  2. 从您的系统上传requests和requests-toolbelt库,或直接下载到之前创建的lib文件夹中。
  3. 使用pip(版本6或更高版本)和-t标志将库复制到您在上一步中创建的文件夹中。例如: pip install -t lib/ (pip install -t lib/ requests)
  4. 在与app.yaml文件相同的文件夹中创建一个名为appengine_config.py的文件。
  5. 编辑appengine_config.py文件,并向vendor.add()方法提供您的库目录。 示例appengine_config.py文件

    from google.appengine.ext import vendor
    # Add any libraries install in the "lib" folder.
    vendor.add('lib/requests')
    vendor.add('lib/requests_toolbelt')
    
  6. 安装后,使用requests_toolbelt.adapters.appengine模块配置请求以使用URLFetch。 将以下代码复制到您的main.py文件开头

    import requests
    from requests_toolbelt.adapters import appengine
    appengine.monkeypatch(validate_certificate=True)
    

(https://cloud.google.com/appengine/docs/standard/python/issue-requests)

现在我们可以轻松使用requests库来进行get/post请求。 测试你的应用程序:

dev_appserver.py --port=<port number> app.yaml

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接