Reputation: 96
I am looking for a solution to run a function that takes 40min to execute. I saw in the docs that a HTTP function can run up to 60min. So I created a function "enqueue_task" that creates a CloudTask that invokes my "long running function". In the simulator I can run "enqueue_task" and it works, but when I deploy this function I get the exception "400 Request contains an invalid argument"
from firebase_functions import firestore_fn, https_fn
# The Firebase Admin SDK to access Cloud Firestore.
from firebase_admin import initialize_app, firestore, functions
import google.cloud.firestore
# Dependencies for task queue functions.
from google.cloud import tasks_v2
# import requests
from firebase_functions.options import RetryConfig, RateLimits, SupportedRegion
from google.auth.transport.requests import AuthorizedSession
import os, json
from dotenv import load_dotenv
import traceback
@https_fn.on_request()
def enqueue_task(req: https_fn.Request) -> https_fn.Response:
"""Adds tasks to a Cloud Tasks queue."""
credentials, _ = google.auth.default(
scopes=["https://www.googleapis.com/auth/cloud-platform"])
print("service account:", credentials.service_account_email)
# this is the URL of my long running task
url = "https://addmessage-XXXXX-uc.a.run.app/addmessage?text=nodanoda44444"
# Create a Cloud Tasks client.
client = tasks_v2.CloudTasksClient()
parent = client.queue_path(project=app.project_id, location="us-central1", queue="q-teste")
task = {
"http_request": { # Specify the type of request.
"http_method": tasks_v2.HttpMethod.POST,
"url": url,
"oidc_token": {
"service_account_email": credentials.service_account_email
},
}
}
# Use the client to build and send the task.
try:
response = client.create_task(parent=parent, task=task)
print(f"Created task {response.name}")
return https_fn.Response(f"Created task {response.name}")
except Exception as e:
print(f"Error creating task {e}")
print(traceback.format_exc())
return https_fn.Response(f"Error creating task ", status=400)
When I run in the emulator I am able to call my long running function, but the deployed version says "400 Request contains an invalid argument"
The line with the error is:
response = client.create_task(parent=parent, task=task)
Upvotes: 0
Views: 84
Reputation: 96
The problem seems to be permission, I was able to set a new service account and worked with the following code
from google.oauth2 import service_account
encoded_cred = os.environ.get('ALT_ACCOUNT')
decoded_cred = base64.b64decode(encoded_cred)
alt_account = json.loads(decoded_cred.decode('utf-8'))
alt_credentials = service_account.Credentials.from_service_account_info(alt_account)
Now in my function I call
client = tasks_v2.CloudTasksClient(credentials=alt_credentials)
I was able add the task to the queue, but the task has a max timeout of 30s so seems to not be possible to run a long function.
Upvotes: 1