Thank you for your interest in contributing! This guide will help you get set up for development.
The build process requires several tools to be installed:
-
Python 3.12+
python --version # Should be 3.12 or higher -
uv - Python package manager
-
Rust toolchain (stable)
-
wasm32-unknown-unknown Rust target (required by build.rs)
rustup target add wasm32-unknown-unknown
-
wasm-tools (required by build.rs for WIT merging and componentization)
-
Viceroy - Fastly's local testing server
The fastly-compute-py build tool is written in Rust. By default, the Makefile uses cargo run (DEV_MODE=1), which means:
- No installation needed for testing or use against examples; the tool runs directly via cargo
- Always up-to-date. Changes to Rust code are automatically picked up.
- Fast incremental builds. Cargo handles recompilation efficiently.
To work on the build tool, edit the Rust code in crates/fastly-compute-py/, then run make to build it.
The build tool is written in Rust and lives in crates/fastly-compute-py/. After you make changes, the Makefile automatically rebuilds via cargo run when you build an example service, like this:
make build/bottle-app.composed.wasmYou can also test the installed entry point, which lets Python code call the build tool:
make DEV_MODE=0 build/bottle-app.composed.wasmThese will spruce up spelling in both Python and Rust code:
make format # Format code
make format-check # Check formatting
make lint # Run linters
make lint-fix # Auto-fix linting issuesThe SDK has comprehensive tests, with integration tests running via Viceroy:
make test # Run all tests
make test-update-snapshots # Update snapshot tests.
βββ crates/
β βββ fastly-compute-py/ # Rust build tool
β β βββ build.rs # Build script (requires wasm-tools)
β β βββ src/
β βββ wasiless/ # Wasm component for WASI stubbing
βββ examples/ # Example applications
β βββ bottle-app/
β βββ flask-app/
β βββ ...
βββ fastly_compute/ # Python SDK
βββ wit/ # WIT (WebAssembly Interface Type) definitions
βββ tests/ # Integration tests
Understanding the build process helps when debugging issues:
-
build.rs (during Rust compilation)...
- Calls
wasm-tools component witto merge WIT files - Builds
wasilesscrate for wasm32-unknown-unknown - Calls
wasm-tools component newto componentize wasiless
- Calls
-
fastly-compute-py...
- Resolves Python dependencies from virtualenv
- Calls
componentize-pyto build Python Wasm component - Composes with wasiless using
wac
The CI workflow (.github/workflows/python-ci.yml) validates formatting,
linting, and tests on every push and pull request. The release workflow
(.github/workflows/release.yml) builds binary wheels for all supported
platforms (Linux x86_64/aarch64, macOS x86_64/aarch64) and attaches them
to a GitHub pre-release.
Releases are driven by a git tag. The release workflow builds binary wheels and attaches them to a GitHub pre-release for validation before PyPI publishing.
The version must be kept in sync across several files including pyproject.toml, crates/fastly-compute-py/Cargo.toml, and all workspace uv.lock / lockfiles.
make lint checks these are in sync.
-
Use the automated version bump helper to update versions and synchronize all cargo/uv lockfiles across the workspace and examples:
make bump-version VERSION=0.2.0
-
PR the changes and land into main.
-
Push tag (make sure you are on the right sha first)
git tag v0.2.0 git push origin v0.2.0 -
The release workflow runs automatically. Jobs:
check-version(fails fast on any mismatch) β parallel wheel + sdist builds βcollect-artifactsβcreate-github-release. -
If the release workflow succeeds, a new pre-release will be available on GitHub. Afer review and update of the generated changelog, use the GitHub UI to transition the release to no longer being a pre-release. This will trigger the publish workflow and push a new release to PyPI.