1

I have created a Google Cloud function that can be invoked through HTTP. The access to the function is limited to the Service account only.

If I had a Django View which should invoke this function and expect a response?

Here is what I have tried

1) Before starting Django I set the environment variable

export GOOGLE_APPLICATION_CREDENTIALS

2) I tried invoking the function using a standalone code, but soon realised this was going nowhere, because I could not figure out the next step after this.

from google.oauth2 import service_account
from apiclient.http import call

SCOPES = ['https://www.googleapis.com/auth/cloud-platform']
SERVICE_ACCOUNT_FILE = 'credentials/credentials.json'

credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

Google's documentation does give you documentation around the API, but there is no sample code on how to invoke the methods or what to import within your Python code and what are the ways to invoke those methods.

How do you send a POST request with JSON data to an Cloud Function, with authorization through a service account?

**Edit A couple hours later I did some more digging and figured this out partially

from google.oauth2 import service_account

import googleapiclient.discovery
import json
SCOPES = ['https://www.googleapis.com/auth/cloud-platform']
SERVICE_ACCOUNT_FILE = 'credentials/credentials.json'

credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

cloudfunction = googleapiclient.discovery.build('cloudfunctions', 'v1', credentials=credentials)
#projects/{project_id}/locations/{location_id}/functions/{function_id}.
path='some project path'
data='some data in json that works when invoked through the console'
data=json.dumps(data)
a=cloudfunction.projects().locations().functions().call(name=path, body=data).execute()

I get another error now.

 Details: "[{'@type': 'type.googleapis.com/google.rpc.BadRequest', 'fieldViolations': [{'description': 'Invalid JSON payload received. Unknown name "": Root element must be a message.'}]}]">

I cant find any documentation on this. How should the JSON be formed?

making the json like {"message":{my actual payload}} doesn't work.

Rupin
  • 610
  • 7
  • 23

1 Answers1

1

The requested documentation can be found here.

The request body argument should be an object with the following form:

{ # Request for the `CallFunction` method.
    "data": "A String", # Input to be passed to the function.
}

The following modification on your code should work correctly:

from google.oauth2 import service_account
import googleapiclient.discovery

SCOPES = ['https://www.googleapis.com/auth/cloud-platform']
SERVICE_ACCOUNT_FILE = 'credentials/credentials.json'

credentials = service_account.Credentials.from_service_account_file(
        SERVICE_ACCOUNT_FILE, scopes=SCOPES)

cloudfunction = googleapiclient.discovery.build('cloudfunctions', 'v1', credentials=credentials)
path ="projects/your-project-name/locations/cloud-function-location/functions/name-of-cloud-function"
data = {"data": "A String"}
a=cloudfunction.projects().locations().functions().call(name=path, body=data).execute()

Notice that very limited traffic is allowed since there are limits to the API calls.

Daniel Ocando
  • 3,554
  • 2
  • 11
  • 19
  • Thank you for your response. Let me try executing this. the documentation says Function invocations per second, 100,000,000 per 100 seconds. I don't foresee this happening any time soon. – Rupin Oct 25 '19 at 05:11
  • Remember you are using the API call method. The limit reduces to 16 calls per 100 seconds. Keep in mind that this API is meant for testing. I wouldn't recommend you to use it in production. – Daniel Ocando Oct 25 '19 at 07:13
  • By issuing an HTTP request using the POST HTTP method with the appropriate headers and authentication to your Cloud Function's URL in the form `https://YOUR_REGION-YOUR_PROJECT_ID.cloudfunctions.net/FUNCTION_NAME`. You can found an example with Python [here](https://cloud.google.com/functions/docs/calling/http#functions-calling-http-python). – Daniel Ocando Oct 25 '19 at 14:49
  • Can you point me to sample code which has the information about how to make that call, with Authorisation? I understand a Bearer token is required, but I don't know how to generate one. – Rupin Oct 25 '19 at 15:20
  • The requested information can be found [here](https://stackoverflow.com/questions/46466607/how-to-obtain-a-gcp-bearer-token-programatically) or [here](https://stackoverflow.com/questions/53472429/how-to-get-a-gcp-bearer-token-programmatically-with-python). But notice that Cloud functions are publicly invokable by default, and as of now you don't need the Bearer token. Although this will change after November 1st 2019, find all the relevant information [here](https://cloud.google.com/functions/docs/securing/authenticating). – Daniel Ocando Oct 26 '19 at 22:58