Thanks for taking the time to contribute! This document explains how to set up a development environment, run the checks, and ship a release.
The project uses uv for environment management and hatchling as the build backend (src layout).
git clone https://github.com/coder2077/fastsaver.git
cd fastsaver
# Create .venv and install the package (editable) plus the "dev" dependency group
uv sync
# Run the checks
.venv/bin/python -m pytest tests
.venv/bin/ruff check src tests examples
.venv/bin/ruff format --check src tests examples
.venv/bin/mypyuv run <cmd> works as well (for example uv run pytest). To test against a
specific interpreter use uv sync --python 3.9 (the package supports 3.9–3.14).
Auto-format before committing:
.venv/bin/ruff format src tests examples
.venv/bin/ruff check --fix src tests examplesThe regular test-suite is fully mocked with respx and needs no network access.
tests/test_live.py talks to the real API and is skipped unless both of the
following environment variables are set:
export FASTSAVER_API_KEY="fs_sk_..." # your own key from https://api.fastsaver.io
export FASTSAVER_LIVE=1
.venv/bin/python -m pytest tests/test_live.pyLive tests call balance() (free) and perform a single fetch(), which costs a
couple of credits. Never paste a real key into source code, fixtures or CI logs —
tests use fake keys such as fs_sk_test_....
- Open an issue first for larger changes so we can agree on the design.
- Keep pull requests focused; one topic per PR.
- Add or update tests for every behaviour change (sync and async where applicable).
- Make sure
pytest,ruff check,ruff format --checkandmypyall pass locally; CI runs the same commands on Python 3.9–3.14. - Keep the public API in sync between
FastSaverandAsyncFastSaver. - Models must parse leniently (missing keys ->
None/empty, unknown keys ignored). - Code comments, docstrings and docs are written in English.
- Update
CHANGELOG.mdunder the[Unreleased]heading. - Use
from __future__ import annotationsand Python 3.9 compatible syntax.
-
Bump the version in
src/fastsaver/_version.py. -
Move the
[Unreleased]entries inCHANGELOG.mdunder a new## [X.Y.Z] - YYYY-MM-DDheading and update the comparison links at the bottom. -
Commit and push to
main, then tag and push the tag:git tag vX.Y.Z git push origin vX.Y.Z
-
Create a GitHub Release from the
vX.Y.Ztag (copy the changelog entry into the release notes). Publishing the release triggers.github/workflows/publish.yml, which builds the sdist/wheel withuv build, verifies them withtwine checkand uploads them to PyPI using Trusted Publishing (OIDC) — no API token is stored in the repository.
Trusted Publishing has to be configured once on PyPI so that GitHub Actions is
allowed to upload the fastsaver project:
- Log in to https://pypi.org and open the project page for
fastsaver(for the very first release use https://pypi.org/manage/account/publishing/ and add a pending publisher — the project is created on the first upload). - Under Publishing -> Add a new publisher choose GitHub and fill in:
- Owner:
coder2077 - Repository name:
fastsaver - Workflow name:
publish.yml - Environment name:
pypi
- Owner:
- In the GitHub repository go to Settings -> Environments, create an
environment called
pypiand (recommended) add required reviewers so a human approves every upload.
The workflow requests id-token: write permission, which is all
pypa/gh-action-pypi-publish needs to exchange the GitHub OIDC token for a
short-lived PyPI upload token.
Be kind and constructive. Harassment or disrespectful behaviour is not tolerated.
Open a GitHub Discussion/Issue, join the Telegram channel https://t.me/fastsaverapi or e-mail support@fastsaver.io.