I've been trying to write and deploy a cloud function in Python. (gave up on node.js due to the messy documentation and relatively fast pace of changes)
It is meant to publish a message to a Pub/Sub topic, triggered when a file finishes being uploaded into google cloud bucket ("finalize").
The code I use to deploy the function is
gcloud functions deploy hello_gcs_generic --runtime python37 --trigger-resource bucketcfpubsub
I have been trying by using this script provided by Google
import time
from google.cloud import pubsub_v1
project_id = "bucketcfpubsub"
topic_name = "projects/bucketcfpubsub/topics/pubsub"
publisher = pubsub_v1.PublisherClient()
topic_path = publisher.topic_path(project_id, topic_name)
def callback(message_future):
# When timeout is unspecified, the exception method waits indefinitely.
if message_future.exception(timeout=30):
print('Publishing message on {} threw an Exception {}.'.format(
topic_name, message_future.exception()))
else:
print(message_future.result())
for n in range(1, 10):
data = u'Message number {}'.format(n)
# Data must be a bytestring
data = data.encode('utf-8')
# When you publish a message, the client returns a Future.
message_future = publisher.publish(topic_path, data=data)
message_future.add_done_callback(callback)
print('Published message IDs:')
# We must keep the main thread from exiting to allow it to process
# messages in the background.
while True:
time.sleep(60)
To which I receive these errors in Google Cloud Console
ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Function load error: Code in file main.py can't be loaded.
Detailed stack trace: Traceback (most recent call last):
File "/env/local/lib/python3.7/site-packages/google/cloud/functions_v1beta2/worker.py", line 256, in check_or_load_user_function
_function_handler.load_user_function()
File "/env/local/lib/python3.7/site-packages/google/cloud/functions_v1beta2/worker.py", line 166, in load_user_function
spec.loader.exec_module(main)
File "<frozen importlib._bootstrap_external>", line 728, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "<frozen importlib._bootstrap_external>", line 728, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/user_code/main.py", line 3, in <module>
from google.cloud import pubsub_v1
ImportError: cannot import name 'pubsub_v1' from 'google.cloud' (unknown location)
Following instruction from these two posts, I've copied the requirements.txt from the helloworld code sample, containing just
google-cloud-error-reporting==0.30.0
and updated other cloud functions like bigquery, storage, and logging. I then got these errors:
ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Function load error: Code in file main.py can't be loaded.
Detailed stack trace: Traceback (most recent call last):
File "/env/local/lib/python3.7/site-packages/google/cloud/functions_v1beta2/worker.py", line 256, in check_or_load_user_function
_function_handler.load_user_function()
File "/env/local/lib/python3.7/site-packages/google/cloud/functions_v1beta2/worker.py", line 166, in load_user_function
spec.loader.exec_module(main)
File "<frozen importlib._bootstrap_external>", line 728, in exec_module
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/user_code/main.py", line 3, in <module>
from google.cloud import pubsub_v1`
and I also found [this thread](ImportError: cannot import name 'pubsub_v1' from 'google.cloud' (unknown location) but I don't really understand what's the solution, I've tried replacing pubsub_v1 with google-cloud-pubsub==0.38.0 which did not help. I get this error instead:
Deploying function (may take a while - up to 2 minutes)...failed.
ERROR: (gcloud.functions.deploy) OperationError: code=3, message=Function load error: Code in file main.py can't be loaded.
Detailed stack trace: Traceback (most recent call last):
File "/env/local/lib/python3.7/site-packages/google/cloud/functions_v1beta2/worker.py", line 256, in check_or_load_user_function
_function_handler.load_user_function()
File "/env/local/lib/python3.7/site-packages/google/cloud/functions_v1beta2/worker.py", line 166, in load_user_function
spec.loader.exec_module(main)
File "<frozen importlib._bootstrap_external>", line 724, in exec_module
File "<frozen importlib._bootstrap_external>", line 860, in get_code
File "<frozen importlib._bootstrap_external>", line 791, in source_to_code
File "<frozen importlib._bootstrap>", line 219, in _call_with_frames_removed
File "/user_code/main.py", line 3
Also, this does not seem to be a sustainable fix if the code will break once Google updates pubsub to a new version?
So I'm very much a beginner and quite lost, but I hope this documentation could help you guys help me.
UPDATE:
It seems pubsub and pubsub_v1 are both valid to be used, not sure what's the difference, though.
@dustin I did a pip install -r requirements.txt which ended up matchiing what you provided. I've also noticed an error in deploying the function as 'hello-gcs-generic', which should be changed to 'callback'.
The python code now runs well locally, but deploying it to the cloud using the above code (the first code line in the OP) consistently returns this error
ERROR: (gcloud.functions.deploy) OperationError: code=3, messa
ge=Function load error: Error: function load attempt timed out
.
For Cloud Functions (1st gen): In the Trigger type field, select Cloud Pub/Sub. In the Select a Cloud Pub/Sub topic field, select a topic for the trigger to monitor. Messages published to this topic will trigger calls to your function.
You need to create a service account to associate with your Pub/Sub subscription, and give it the permission to invoke your Cloud Run service. Pub/Sub messages pushed to your Cloud Run service will carry the identity of this service account.
Setup a Google Cloud Pub/Sub 1.2 Set up a Cloud Console project in a PubSub section https://cloud.google.com/pubsub. Create or select a project and enable the Pub/Sub API for that project. You can view and manage these resources at any time in the Cloud Console. 1.3 Set up a topic where your data shall be sent to.
You need to add google-cloud-pubsub
to your requirements.txt
file, not in your main.py
file. It should look like this:
google-cloud-error-reporting==0.30.0
google-cloud-pubsub==0.38.0
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With