Python on the Compute platform
The Compute platform supports application code written in Python, a popular, readable language with a large ecosystem of libraries. The Python SDK builds your Python application into a WebAssembly (Wasm) component that runs on the Compute platform.
IMPORTANT: This information is part of a beta release. For additional details, read our product and feature lifecycle descriptions.
Quick access
Python language support
The Compute platform's Python SDK requires Python 3.12 or later. The SDK is distributed as the fastly-compute package and installs the fastly-compute-py build tool used to produce a Wasm component from your Python code.
Because the build process compiles your application to WebAssembly, some Python features are not yet available on the platform. In particular, third-party 'native code' extension modules are not currently supported. See Caveats for the full list.
Project layout
If you don't yet have a working toolchain and Compute service set up, start by getting set up.
To work with the Python SDK, you need two system dependencies installed:
- The Fastly CLI, version 15.5.0 or later. Earlier versions don't recognize Python as a Compute language.
- The
uvPython package manager, version 0.5.0 or later.
uv installs and manages the Python SDK and build tooling in an isolated environment, so you don't need to install those globally.
To create a project, run fastly compute init in an empty directory and choose Python when prompted for a language, then select a starter kit:
$ mkdir my-compute-service$ cd my-compute-service$ fastly compute initThe CLI generates the fastly.toml metadata file and the project files from the starter kit you chose. The current working directory will contain a file tree resembling the following:
├── .gitignore├── README.md├── fastly.toml├── main.py├── pyproject.toml└── welcome-to-compute.htmlThe most important file to work on is main.py, which contains the logic you'll run on incoming requests. If you initialized your project from the default starter kit, the contents of this file will match the one in the template's repository. The other files include:
- Python project metadata:
pyproject.tomldescribes the dependencies of your project, managed usinguv. Running a build also creates auv.lockfile that pins the resolved versions. Add further dependencies with uv add, for example uv add flask. - Fastly metadata: The
fastly.tomlfile contains metadata required by Fastly to deploy your package to a Fastly service. It is generated by the fastly compute init command. Learn more aboutfastly.toml.
Building and deploying
Use fastly compute build to build a Wasm component from your project, fastly compute serve to test your service locally, and fastly compute deploy to deploy it to Fastly.
The CLI builds Python projects by running uv run fastly-compute-py build for you, so you don't need to set the scripts.build property in fastly.toml. To customize the build, set it explicitly:
[scripts]build = "uv run fastly-compute-py build"The fastly-compute-py build tool determines which module contains your service from the [tool.fastly-compute] section of your pyproject.toml. Starter kits set this for you, pointing entry at your module (without the .py extension):
[tool.fastly-compute]entry = "main"Main interface
The most common way to build a Compute program in Python is to write a standard WSGI application and wrap it with WsgiHttpIncoming. This lets you use familiar web frameworks such as Flask or Bottle:
123456789101112from flask import Flaskfrom fastly_compute.wsgi import WsgiHttpIncoming
app = Flask(__name__)
@app.route("/")def index(): return "Hello from Python on Fastly Compute!"
HttpIncoming = WsgiHttpIncoming(app)WsgiHttpIncoming adapts your WSGI application to Fastly's incoming request handler. The module assigned to HttpIncoming is invoked for each request that Fastly receives for a domain attached to your service, and it must produce a response that can be served to the client.
HINT: All packages needed at runtime must be imported when your entry point module is imported, so that the SDK's memory-snapshotting build process can retain them. Avoid deferred (non-top-level) imports in code that runs at request time. Refer to Caveats for more information.
You can also write directly against Fastly's API instead of using a WSGI framework, which is useful for services that don't fit the request/response model of a web framework.
Communicating with backend servers and the Fastly cache
Requests to a backend defined on your service are made using the fastly_compute.requests module, which provides a familiar requests-compatible HTTP client. If you specify a backend hostname as part of completing the fastly compute deploy wizard, it will be named the same as the hostname or IP address, but with . replaced with _ (e.g., 151_101_129_57).
Use the fastly_backend keyword argument to send a request to a named backend:
import fastly_compute.requests as requests
BACKEND_NAME = "my_backend_name"
response = requests.get("https://example.com/api/getFlags", fastly_backend=BACKEND_NAME)Requests forwarded to a backend will typically transit the Fastly cache, and the response may come from cache. For more precise or explicit control over the Fastly edge cache, refer to Caching content with Fastly.
The Python SDK also supports dynamic backends. If you make a request to a full URL without specifying a fastly_backend, a backend for that origin is created dynamically at runtime:
import fastly_compute.requests as requests
# Uses a dynamically created backend for the request's originresponse = requests.get("https://http-me.fastly.dev/get")Fastly-specific timeouts can be configured with TimeoutConfig:
1234567891011121314import fastly_compute.requests as requestsfrom fastly_compute.requests import TimeoutConfig
timeout_config = TimeoutConfig( connect=5.0, # 5s to establish a connection first_byte=30.0, # 30s to receive the first byte between_bytes=2.0 # 2s max between bytes)
response = requests.get( "https://api.example.com/data", fastly_backend="api-backend", fastly_timeout=timeout_config,)Compression
Fastly can compress and decompress content automatically, and it is often easier to use these features than to try to perform compression or decompression within your Python code. Learn more about compression with Fastly.
Composing requests and responses
In addition to forwarding requests to backends, you can construct requests and read structured responses using the fastly_compute.requests module. This is useful if you want to make an arbitrary API call that is not derived from the client request. The response object exposes the same attributes you'd expect from the requests library, such as status_code, headers, text, content, and ok, along with helpers like json():
123456789import fastly_compute.requests as requests
response = requests.post( "https://http-me.fastly.dev/post", json={"key": "value"},)
if response.ok: data = response.json()When you build your service on a WSGI framework, you construct responses to the client using that framework's own primitives (for example, returning a string, tuple, or response object from a Flask view). Refer to your framework's documentation for details.
Parsing and transforming responses
Reading a backend response's body into memory (for example, via response.text or response.content) will consume the entire body into memory. This can be appropriate where a response is known to be small or needs to be complete to be parsable, such as when parsing JSON. For large payloads, prefer to stream the response through your service rather than buffering it in full.
This example reads a backend response and replaces every occurrence of "cat" with "dog" before returning it:
123456789101112131415161718import fastly_compute.requests as requestsfrom flask import Flask, Responsefrom fastly_compute.wsgi import WsgiHttpIncoming
app = Flask(__name__)
@app.route("/")def transform(): backend_response = requests.get( "https://http-me.fastly.dev/get", fastly_backend="my_backend_name", ) body = backend_response.text.replace("cat", "dog") return Response(body, status=backend_response.status_code)
HttpIncoming = WsgiHttpIncoming(app)Using edge data
Fastly allows you to configure various forms of data stores for your services, both for dynamic configuration and for storing data at the edge. The Python SDK exposes the config_store module for read-only access to config stores:
from fastly_compute.config_store import ConfigStore
with ConfigStore.open("my-config") as config: api_url = config.get("api_url", "https://api.example.com")All edge data resources are account-level, service-linked resources, allowing a single store to be accessed from multiple Fastly services.
Logging
The fastly_compute.log module provides an interface for sending logs to Fastly real-time logging, which can be attached to many third-party logging providers. Before adding logging code to your Compute program, set up your log endpoint using the CLI, API, or web interface. Log endpoints are referenced in your code by name.
You can write to an endpoint directly:
from fastly_compute.log import LogEndpoint
endpoint = LogEndpoint.open("my_logs")endpoint.write("Hello from Fastly Compute!")The SDK also provides FastlyLogHandler, so you can route Python's standard logging module to a Fastly endpoint:
12345678import loggingfrom fastly_compute.log import FastlyLogHandler
logger = logging.getLogger("my_app")logger.setLevel(logging.INFO)logger.addHandler(FastlyLogHandler("my_logs"))
logger.info("Request processed")Using dependencies
The Compute build process compiles your code to WebAssembly, so it supports pure Python dependencies. Add packages to your project with uv add, and they'll be managed in your pyproject.toml and uv.lock. WSGI web frameworks such as Flask and Bottle are known to work.
Third-party 'native code' extension modules are not currently supported. All packages needed at runtime must be imported when your entry point module is imported, so avoid deferred (non-top-level) imports in code that runs at request time.
Testing and debugging
Logging is the main mechanism to debug Compute programs. Log output from live services can be monitored via live log tailing. The local test server displays all log output automatically. Refer to Testing & debugging for more information about choosing an environment in which to test your program.
You can run your service locally with fastly compute serve, which builds and serves your project so you can exercise it with real requests before deploying.
Caveats
The Python SDK is available as part of Fastly's Beta program, and there are some limitations to be aware of:
- Its in-Python API may change in backward-incompatible ways during the beta period.
- Third-party 'native code' extension modules are not yet supported.
- All packages needed at runtime must be imported when your entry point module is imported, so that the SDK's memory-snapshotting build process can retain them. This can happen transitively, but beware of deferred imports (such as non-top-level imports); if they aren't triggered by importing your entry point, they will fail at runtime. If you use third-party code that relies on non-top-level imports, you can ensure it works by importing it at the top level in your own code.