Functions Framework turns a plain Python function into an endpoint
FaaS (Function as a service) framework for writing portable Python functions
At a glance
- What is it?
- The Functions Framework for Python is the Google Cloud Functions team's open source FaaS framework, and its promise is portability: write a function that takes a request, and run it on your laptop, on Google Cloud Run Functions, or on a Knative based platform. The mechanism is a Flask application underneath, with decorators that choose the signature your function expects.
- Who is it for?
- Functions Framework for Python fits a team that wants to develop a serverless function with a local HTTP server and a curl command instead of a deploy cycle, and it fits a team that needs the same code to run on more than one serverless platform, since Cloud Run Functions and Knative are both listed as targets.
- Can I use it commercially?
- Yes. Apache-2.0 is a permissive licence: you can use, modify and sell software built on it, as long as you keep its copyright and licence notices.
- Is it still maintained?
- Yes. The repository last received commits 79 days ago.
- What is it written in?
- Mainly Python, according to GitHub's language statistics.
Answers come from the project's GitHub data, last synced on October 23, 2026, and from our analysis. They are not legal advice.
Editorial analysis
The whole idea in one function
The framework's pitch is shown as a before and after. You start with a function that takes a request and returns a string:
def hello(request):
return "Hello world!"and you end up with an HTTP endpoint that answers a curl. The point of the framing is that you never write an HTTP server or complicated request handling logic, and the environments the framework targets are listed as Google Cloud Run Functions, your local development machine, and Knative based environments. The portability claim is the interesting part of the product, because the same decorator and the same function body have to satisfy three different runtimes, which is a constraint that shapes the whole design. The feature list spells out the four capabilities: spin up a local development server for quick testing, invoke a function in response to a request, automatically unmarshal events conforming to the CloudEvents spec, and be portable between serverless platforms.
An HTTP function is a Flask view
The hello world quickstart is short enough to be the whole API surface. You create a main.py that imports Flask and the framework, decorate a function, and return a value:
import flask
import functions_framework
@functions_framework.http
def hello(request: flask.Request) -> flask.typing.ResponseReturnValue:
return "Hello world!"The single parameter is a Flask Request object, and the type annotation shows the intended style, since the framework is a thin layer over Flask rather than a replacement for it. The command to run it locally names the target and asks for debug mode:
functions-framework --target hello --debugThe startup output makes the state of the process explicit, including a warning that this is a development server and that a production WSGI server should be used instead. The server listens on port 8080, and the README notes that the functions-framework-python name can be used instead if you have several language frameworks installed at once. Once it is running, a browser or a curl against localhost:8080 gets the return value of your function.
CloudEvent functions for event driven platforms
The second quickstart covers the CloudEvents style, where the argument is a CloudEvent rather than a request. The function is decorated with cloud_event instead of http, and the payload arrives already unmarshalled:
import functions_framework
from cloudevents.http.event import CloudEvent
@functions_framework.cloud_event
def hello_cloud_event(cloud_event: CloudEvent) -> None:
print(f"Received event with ID: {cloud_event['id']} and data {cloud_event.data}")The function is started with the target given in the long form, and the event is then posted to the local server with the content type set to the CloudEvents JSON media type and a body carrying the spec version, the type, the source, a subject, an id, a time and the data. The terminal running the framework then prints the event id and the data, which is the quick confirmation that the unmarshalling worked. There is a linked example directory for Cloud Run with CloudEvents if you want the deployment side, and the cloudevents package is a hard dependency of the framework rather than an optional extra.
Errors handled by a decorator
The framework ships an error handler that is similar to the Flask errorhandler function, which means you can handle specific error types with a decorator rather than a try block. The quickstart is deliberately funny, dividing by zero in a function that would otherwise succeed:
import functions_framework
@functions_framework.errorhandler(ZeroDivisionError)
def handle_zero_division(e):
return "I'm a teapot", 418
def function(request):
1 / 0
return "Success", 200The handler catches the ZeroDivisionError and returns a different response, a 418 status with a teapot message, instead of the success the function intended to return. The pattern is the same one a Flask application would use, which is the point, since the framework is meant to feel like something you already know rather than a new programming model. The errorhandler decorator is registered for the exception type, and the handler returns a response tuple in the usual Flask way.
Background events and the Pub/Sub emulator
The third quickstart shows the background event signature, which is the style used by Google Cloud functions triggered by a queue or a topic. The function takes two parameters, the event and the context, and reads the event id off the context. It is served locally by pointing the framework at a different signature type:
functions-framework --target=hello --signature-type=event --debug --port=8080The rest of the quickstart is a local Pub/Sub setup, which is where it gets long. You start the Pub/Sub emulator on port 8085 with a project id set in the environment, create a topic and a push subscription whose push endpoint is the local framework, and publish messages to see the function fire. The emulator is started with the gcloud beta emulators pubsub start command and the project flag, and the publisher and subscriber scripts come from a clone of the python-pubsub repository. The value of the exercise is that you can test an event triggered function end to end, including the push subscription behaviour, without touching a real Google Cloud project.
One entry point, four command names
The packaging is unusually generous about names, and the reason is practical rather than decorative. The project scripts section declares five console entry points that all point at the same function, functions_framework._cli:_cli. They are ff, functions-framework, functions_framework, functions-framework-python and functions_framework_python, with the last one existing for the case where several language frameworks are installed at once and a bare name would be ambiguous. The package itself is on PyPI as functions-framework, and the installation instructions give the pip command and, for deployment, the requirements.txt line that pins the major version. The examples directory shows the full matrix of what the framework supports in the wild, with directories for Cloud Run with async, Cloud Run with CloudEvents, Cloud Run with the decorator, Cloud Run with event functions, Cloud Run with HTTP, Cloud Run with streaming HTTP, plus docker-compose and skaffold setups. That directory listing is the most complete description of the supported deployment shapes.
Dependencies, tooling and release state
The dependency list is where the Flask story becomes concrete, with flask constrained to a range of 2.0 up to but not including 4.0, Werkzeug for the WSGI layer, click for the command line, and watchdog for the file watching that makes live reload work. The server side depends on gunicorn on platforms other than Windows, and on uvicorn with uvicorn-worker, which is how the newer async style is served. The CloudEvents dependency is pinned to a narrow range, with a comment in the file noting it must support Python 3.8, and the starlette requirement is split by Python version, with one range for 3.8 and 3.9 and another for 3.10 and later. The project declares Python 3.7 and later as the supported range, with classifiers up to 3.12, and the package is marked as Production/Stable. The repository adds tox.ini, a conftest.py, a setup.py and a setup.cfg alongside the pyproject, and a.kokoro directory for the internal build system, plus a DEVELOPMENT.md. The releases are 3.10.2 from 2026-06-17, 3.10.1 from 2026-02-17 and 3.10.0 from 2025-11-10, and the last push was on 2026-08-05, with the project under the Apache-2.0 licence.
Editorial conclusion
Functions Framework for Python fits a team that wants to develop a serverless function with a local HTTP server and a curl command instead of a deploy cycle, and it fits a team that needs the same code to run on more than one serverless platform, since Cloud Run Functions and Knative are both listed as targets. It does not fit someone who wants a framework with more than the four entry point styles, and it does not fit a project that wants to avoid Flask in the dependency tree. Before you adopt it, check the Python version you are on, since the package still declares support from 3.7 upwards with a different set of dependencies below 3.10, and note the release state, with 3.10.2 published on 2026-06-17 and the last push on 2026-08-05.
Frequently asked questions
What is the Functions Framework for Python?
It is an open source FaaS framework from the Google Cloud Functions team for writing portable Python functions, letting you develop locally, on Google Cloud Run Functions, or on Knative based platforms without writing an HTTP server or request handling logic yourself.
How do I run a function locally?
Decorate a function with the http decorator and run functions-framework --target hello --debug, which starts a Flask development server on port 8080. The function receives a Flask Request object and its return value becomes the response body.
What function styles does the framework support?
HTTP functions that take a request, CloudEvent functions that take an unmarshalled CloudEvent, and background event functions that take an event and a context, the last selected with the signature-type option and the other two with the http and cloud_event decorators.
How do I handle errors in a function?
With the errorhandler decorator, which works like the Flask errorhandler function. Register a handler for a specific exception type and it returns a response instead of the exception propagating.
Is the Functions Framework still updated?
The repository is not archived and the last push was on 2026-08-05, with releases 3.10.2 from 2026-06-17, 3.10.1 from 2026-02-17 and 3.10.0 from 2025-11-10, under the Apache-2.0 licence.
Official sources
Add this badge to your README
If you maintain this project, the badge below links readers to this analysis and shows its maintenance status from the daily GitHub snapshot. Paste the markdown into your README; add ?metric=license or ?metric=stars to the image URL for a different field.
[](https://hysenlabs.com/projects/googlecloudplatform-functions-framework-python)Was this useful?