functions/helloworld/main.py (82 lines of code) (raw):
# Copyright 2019 Google LLC
#
# Licensed under the Apache License, Version 2.0 (the 'License');
# you may not use this file except in compliance with the License.
# You may obtain a copy of the License at
#
# http://www.apache.org/licenses/LICENSE-2.0
#
# Unless required by applicable law or agreed to in writing, software
# distributed under the License is distributed on an 'AS IS' BASIS,
# WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
# See the License for the specific language governing permissions and
# limitations under the License.
# [START functions_helloworld_http]
# [START functions_http_content]
# [START functions_http_method]
# [START functions_helloworld_get]
import functions_framework
# [END functions_http_method]
# [END functions_helloworld_get]
from markupsafe import escape
# [END functions_helloworld_http]
# [END functions_http_content]
# [START functions_helloworld_get]
@functions_framework.http
def hello_get(request):
"""HTTP Cloud Function.
Args:
request (flask.Request): The request object.
<https://flask.palletsprojects.com/en/1.1.x/api/#incoming-request-data>
Returns:
The response text, or any set of values that can be turned into a
Response object using `make_response`
<https://flask.palletsprojects.com/en/1.1.x/api/#flask.make_response>.
Note:
For more information on how Flask integrates with Cloud
Functions, see the `Writing HTTP functions` page.
<https://cloud.google.com/functions/docs/writing/http#http_frameworks>
"""
return "Hello World!"
# [END functions_helloworld_get]
# [START functions_helloworld_http]
@functions_framework.http
def hello_http(request):
"""HTTP Cloud Function.
Args:
request (flask.Request): The request object.
<https://flask.palletsprojects.com/en/1.1.x/api/#incoming-request-data>
Returns:
The response text, or any set of values that can be turned into a
Response object using `make_response`
<https://flask.palletsprojects.com/en/1.1.x/api/#flask.make_response>.
"""
request_json = request.get_json(silent=True)
request_args = request.args
if request_json and "name" in request_json:
name = request_json["name"]
elif request_args and "name" in request_args:
name = request_args["name"]
else:
name = "World"
return f"Hello {escape(name)}!"
# [END functions_helloworld_http]
# [START functions_helloworld_pubsub]
def hello_pubsub(event, context):
"""Background Cloud Function to be triggered by Pub/Sub.
Args:
event (dict): The dictionary with data specific to this type of
event. The `@type` field maps to
`type.googleapis.com/google.pubsub.v1.PubsubMessage`.
The `data` field maps to the PubsubMessage data
in a base64-encoded string. The `attributes` field maps
to the PubsubMessage attributes if any is present.
context (google.cloud.functions.Context): Metadata of triggering event
including `event_id` which maps to the PubsubMessage
messageId, `timestamp` which maps to the PubsubMessage
publishTime, `event_type` which maps to
`google.pubsub.topic.publish`, and `resource` which is
a dictionary that describes the service API endpoint
pubsub.googleapis.com, the triggering topic's name, and
the triggering event type
`type.googleapis.com/google.pubsub.v1.PubsubMessage`.
Returns:
None. The output is written to Cloud Logging.
"""
import base64
print(
"""This Function was triggered by messageId {} published at {} to {}
""".format(
context.event_id, context.timestamp, context.resource["name"]
)
)
if "data" in event:
name = base64.b64decode(event["data"]).decode("utf-8")
else:
name = "World"
print(f"Hello {name}!")
# [END functions_helloworld_pubsub]
# [START functions_helloworld_storage]
def hello_gcs(event, context):
"""Background Cloud Function to be triggered by Cloud Storage.
This generic function logs relevant data when a file is changed,
and works for all Cloud Storage CRUD operations.
Args:
event (dict): The dictionary with data specific to this type of event.
The `data` field contains a description of the event in
the Cloud Storage `object` format described here:
https://cloud.google.com/storage/docs/json_api/v1/objects#resource
context (google.cloud.functions.Context): Metadata of triggering event.
Returns:
None; the output is written to Cloud Logging
"""
print(f"Event ID: {context.event_id}")
print(f"Event type: {context.event_type}")
print("Bucket: {}".format(event["bucket"]))
print("File: {}".format(event["name"]))
print("Metageneration: {}".format(event["metageneration"]))
print("Created: {}".format(event["timeCreated"]))
print("Updated: {}".format(event["updated"]))
# [END functions_helloworld_storage]
# [START functions_http_content]
@functions_framework.http
def hello_content(request):
"""Responds to an HTTP request using data from the request body parsed
according to the "content-type" header.
Args:
request (flask.Request): The request object.
<https://flask.palletsprojects.com/en/1.1.x/api/#incoming-request-data>
Returns:
The response text, or any set of values that can be turned into a
Response object using `make_response`
<https://flask.palletsprojects.com/en/1.1.x/api/#flask.make_response>.
"""
content_type = request.headers["content-type"]
if content_type == "application/json":
request_json = request.get_json(silent=True)
if request_json and "name" in request_json:
name = request_json["name"]
else:
raise ValueError("JSON is invalid, or missing a 'name' property")
elif content_type == "application/octet-stream":
name = request.data
elif content_type == "text/plain":
name = request.data
elif content_type == "application/x-www-form-urlencoded":
name = request.form.get("name")
else:
raise ValueError(f"Unknown content type: {content_type}")
return f"Hello {escape(name)}!"
# [END functions_http_content]
# [START functions_http_method]
@functions_framework.http
def hello_method(request):
"""Responds to a GET request with "Hello world!". Forbids a PUT request.
Args:
request (flask.Request): The request object.
<https://flask.palletsprojects.com/en/1.1.x/api/#incoming-request-data>
Returns:
The response text, or any set of values that can be turned into a
Response object using `make_response`
<https://flask.palletsprojects.com/en/1.1.x/api/#flask.make_response>.
"""
from flask import abort
if request.method == "GET":
return "Hello World!"
elif request.method == "PUT":
return abort(403)
else:
return abort(405)
# [END functions_http_method]
# [START functions_helloworld_error]
@functions_framework.http
def hello_error_1(request):
# This WILL be reported to Error Reporting,
# and WILL NOT show up in logs or
# terminate the function.
from google.cloud import error_reporting
client = error_reporting.Client()
try:
raise RuntimeError("I failed you")
except RuntimeError:
client.report_exception()
# This WILL be reported to Error Reporting,
# and WILL terminate the function
raise RuntimeError("I failed you")
# [END functions_helloworld_error]
# [START functions_helloworld_error]
@functions_framework.http
def hello_error_2(request):
# These errors WILL NOT be reported to Error
# Reporting, but will show up in logs.
import logging
import sys
print(RuntimeError("I failed you (print to stdout)"))
logging.warning(RuntimeError("I failed you (logging.warning)"))
logging.error(RuntimeError("I failed you (logging.error)"))
sys.stderr.write("I failed you (sys.stderr.write)\n")
# This is considered a successful execution and WILL NOT be reported
# to Error Reporting, but the status code (500) WILL be logged.
from flask import abort
return abort(500)
# [END functions_helloworld_error]