Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Calling a Google Cloud Function from within Python

I'm trying to call a Google Cloud function from within Python using the following:

import requests
url = "MY_CLOUD_FUNCTON_URL"
data = {'name': 'example'}
response = requests.post(url, data = data)

but I get back the error: Your client does not have permission to get URL MY_CLOUD_FUNCTON from this server

Does anyone know how I can avoid this error? I am assuming I should be passing credentials as part of the request somehow?

Also note that if I instead try to call the function via gcloud from the command line like the below then it works, but i want to do this from within python

gcloud functions call MY_CLOUD_FUNCTON --data '{"name": "example"}' 

Any help would be really appreciated!

like image 836
user3472360 Avatar asked Jan 27 '26 23:01

user3472360


2 Answers

Given a working Cloud Function in HTTP mode which requires authentication in order to be triggered.

You need to generate an authentication token and insert it in the header as shown below:

import os
import json
import requests
import google.oauth2.id_token
import google.auth.transport.requests

os.environ['GOOGLE_APPLICATION_CREDENTIALS'] = './my-service-account.json'
request = google.auth.transport.requests.Request()
audience = 'https://mylocation-myprojectname.cloudfunctions.net/MyFunctionName'
TOKEN = google.oauth2.id_token.fetch_id_token(request, audience)

r = requests.post(
    audience, 
    headers={'Authorization': f"Bearer {TOKEN}", "Content-Type": "application/json"},
    data=json.dumps({"key": "value"})  # possible request parameters
)
r.status_code, r.reason
like image 110
Marco Cerliani Avatar answered Jan 29 '26 12:01

Marco Cerliani


You have a few options here. Either open the function to the public so that anyone can call it or take the more secure route, albeit necessitating a bit more steps. I will cover the 2nd option since it's the one I would suggest for security reasons, but should you be satisfied with simply opening the function to the public ( which is especially useful if you are trying to create a public endpoint after all ), see this documentation.

If you want to limit who can invoke your GCF however, you would have to perform a few more steps.

  1. Create a service account and give it the Cloud Functions Invoker role ( if you simply want to restrict it's permissions to only invoke the GCF )
  2. After you assign the Service Account a role(s), the next page will give you the option to create a key
  3. After creating the Service Account Key and downloading it as credentials.json, the next step is straightforward. You would simply populate the environment variable GOOGLE_APPLICATION_CREDENTIALS with the path to the credentials.json file.

Once these steps are done, you can simply invoke the GCF as you did before, only this time, it will invoke it as the service account that you created, which contained all the permissions necessary to invoke a GCF.

like image 31
JKleinne Avatar answered Jan 29 '26 11:01

JKleinne