【问题标题】:Python and "import requests" on HTTP Google Cloud FunctionsHTTP Google Cloud Functions 上的 Python 和“导入请求”
【发布时间】:2020-02-13 07:10:02
【问题描述】:

我正在尝试为 Google Cloud 函数创建一个简单的 HTTP 请求,因此当我调用 Google Cloud URL 时,将通过 Mailgun API 发送邮件。

下面是我在 PyCharm 中用于测试连接的非常基本的 Mailgun 代码,一切正常。当我在计算机上运行此功能时,我会在收件箱中收到一封电子邮件。

import requests

def send_simple_message():
    return requests.post(
        "https://api.eu.mailgun.net/v3/mg.my.url.com/messages",
        auth=("api", "XXXXXxKEYxXXXXX"),
        data={"from": "Name <name@mg.my.url.com>",
              "to": "name@outlook.com",
              "subject": "Hello You",
              "text": "Testing some Mailgun awesomness!"})

send_simple_message()

只要我在 GCP 中创建 HTTP 函数并复制/粘贴相同的代码,就会出现错误。唯一的区别是我将requests==2.21.0 添加到requirements.txt 文件中。我相信这会告诉 Google Cloud 在 Python 中包含 requests 模块。

我从日志文件中得到的错误:

错误:函数崩溃。细节: 'Request' 对象没有属性 'post'

我需要向 Python 添加另一个模块吗?


添加了额外的日志信息:

【问题讨论】:

  • 在出现此错误之前,Stackdriver 中是否还有其他消息?您有库版本冲突或缺少库。请注意,请求的当前版本是 2.22.0。
  • 我已经尝试添加最新版本的请求,但这对结果并不重要。因此,我开始在 Cloud Functions 文档中进行搜索,并看到那里使用的是旧版本。这就是我尝试那个版本的原因。
  • 解决这个问题的最简单方法是使用 virtualdev。创建一个目录,然后运行pip install -U requests。 pip freeze 将向您显示 requirements.txt 的导入。 Python 模块requests 依赖于其他模块。在 Cloud Functions 中,您需要指定所有内容,而不是假设 Cloud Functions 会为您解决问题。
  • 您要返回什么?因为当我尝试运行您的代码时,我收到“错误:函数崩溃。详细信息:'响应'对象不可调用视图函数未返回有效响应。返回类型必须是字符串、元组、响应实例,或 WSGI 可调用,但它是一个响应。”重现您的错误的唯一方法是拼写错误“request.post()”
  • 另外你也不需要最后调用“send_simple_message()”,只需在“Function to execute”框中写上“send_simple_message”即可。

标签: python google-cloud-platform google-cloud-functions mailgun


【解决方案1】:

由于我没有付费 Mailgun 帐户,我无法为您提供详细代码,但我建议您从官方 App Engine 中查看此功能,其中还使用了他们设法使用 Mailgun 的响应库。云函数是基于 App Engine 的,因此这必须接近您想要实现的目标。

import os
import pytest
import requests
import responses

@pytest.fixture
def app(monkeypatch):
    monkeypatch.setenv('MAILGUN_DOMAIN_NAME', 'example.com')
    monkeypatch.setenv('MAILGUN_API_KEY', 'apikey')

    import main

    main.app.testing = True
    return main.app.test_client()


@responses.activate
def test_send_simple(app):
    responses.add(
        responses.POST,
        'https://api.mailgun.net/v3/example.com/messages',
        body='')

    response = app.post('/send/email', data={
        'recipient': 'user@example.com',
        'submit': 'Send simple email'})
    assert response.status_code == 200
    assert len(responses.calls) == 1

【讨论】:

  • 库 responses 很棒,但是这个库用于“模拟”测试请求,而不是部署代码。
  • @Jack Ottermans,如果以上答案对您有帮助,请告诉我们?
猜你喜欢
  • 2017-10-31
  • 2020-12-23
  • 1970-01-01
  • 2020-08-17
  • 1970-01-01
  • 2019-05-16
  • 2023-03-08
  • 1970-01-01
  • 2020-11-03
相关资源
最近更新 更多