Python and "import requests" on HTTP Google Cloud Functions

Viewed 3769

I am trying to create a simple HTTP request to a Google Cloud function, so when I call the Google Cloud URL a mail will be sent via the Mailgun API.

Below is the very basic Mailgun code I used in PyCharm to test the connection and everything is working fine. When I run this function on my computer I'll receive an email in my inbox.

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()

As soon as I create an HTTP function in GCP and copy/paste the same code there I get an error. The only difference is I added requests==2.21.0 to the requirements.txt file. I believe this tells Google Cloud to include the requests module in Python.

Error I'm getting from logfile:

Error: function crashed. Details: 'Request' object has no attribute 'post'

Do I need to add another module to Python?


Added extra log information: enter image description here

2 Answers

Since I don't have a paid Mailgun account I can't help you with detailed code but I would suggest you take a look at this function from the official App Engine where using also responses lib they manage to use Mailgun. Cloud functions are based on App Engine so this must be close to what you want to achieve.

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

You should write the import inside your function. Plus it's not necessary to instantiate the request, you should invoke it from the entry point.

Hope it helps,

def send_simple_message():
    import requests
    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()
Related