Contributing¶
Reporting Issues¶
If you are using this package and are encountering issues, please feel free to raise them at on our issue tracker.
Providing Feedback¶
This client was developed with a limited set of use cases in mind. And therein, can be biased in various places. Any feedback regarding what could be improved, added or changes can also be submitted similar to reporting issues, on our issue tracker.
Code Contributions¶
Code contributions in the form of bugfixes, improvements or new features are always welcome. All that we ask, is that you do make sure the rationale for the change is described if it is more than a simple change. The current open change requests can be seen are available here.
Documentation¶
Improvements and additions to our documentation are always welcome. From typo fixes, to documenting undocumented features, or structural changes. Everything is welcome.
Local Development¶
Setting Up¶
To set up your local development environment, you will need Poetry (>= 2.0).
# Install dependencies including all optional extras and dev/test/docs groups
poetry install --all-extras --with dev,test,docs
# Install pre-commit hooks (runs ruff, formatting, and conventional commit checks)
poetry run pre-commit install --hook-type pre-commit --hook-type commit-msg
Running Tests¶
The project uses pytest for testing and tox to manage the test matrix across
Python versions and HTTP transports (aiohttp, httpx, or both).
Integration tests require running GraphQL servers (Hasura, Apollo v2, Strawberry), which
are managed via podman compose (or docker-compose).
# Start test servers
podman compose up -d
# Run the full suite directly with pytest
poetry run pytest
# Or run via tox for a specific Python version and transport combination
poetry run tox -e py312-aiohttp
poetry run tox -e py312-httpx
poetry run tox -e py312-all
The pytest configuration waits up to 300 seconds for the Hasura server to become ready
before running tests, so you do not need to manually verify server readiness after
podman compose up. Tests that depend on Apollo v2 or Strawberry are skipped if the
corresponding server is unavailable.
Coverage data is written to .coverage/ and merged across tox environments. To
generate an HTML report:
poetry run tox -e report
Environment Variables¶
If you need to customize the GraphQL server endpoints for testing, set the following
environment variables (or pass equivalent --server-* options to pytest):
GRAPHQL_ENDPOINT_WORLD_SERVER: Hasura world database endpoint (default:http://127.0.0.1:8080/v1/graphql)GRAPHQL_ENDPOINT_APOLLO_V2: Apollo Server v2 endpoint (default:http://127.0.0.1:4000/graphql)GRAPHQL_ENDPOINT_STRAWBERRY: Strawberry server endpoint (default:http://127.0.0.1:5000/graphql)
Cross-Platform Testing¶
The CI test matrix exercises Python 3.10 through 3.14 across the aiohttp, httpx,
and combined transport configurations on Ubuntu. Contributors typically run tests on
their preferred platform locally; the automated CI ensures the codebase remains
compatible across the supported Python versions.
Code Quality¶
Linting and formatting are handled by Ruff, and type checking by mypy. Both are
configured in pyproject.toml and run automatically via the pre-commit hooks when
installed.
# Lint and auto-fix
poetry run ruff check .
# Format
poetry run ruff format .
# Type-check
poetry run mypy
# Run all pre-commit hooks against the full tree
poetry run pre-commit run --all-files
Building Documentation¶
You can build the documentation locally using tox:
poetry run tox -e docs
The generated documentation will be available in docs/_build/html/index.html.
Commit Messages¶
This project follows the Conventional Commits specification. Commit messages are
validated locally by a pre-commit hook (conventional-pre-commit), and pull request
titles are validated in CI by the PR Title Check workflow.
A typical commit message looks like:
feat(transport): add httpx subscription support
Optional longer description explaining the change.
The commit type drives the automated release process (see below):
feat: a new feature → minor version bumpfix: a bug fix → patch version bumpfeat!/BREAKING CHANGE:footer → major version bumpchore,docs,refactor,test,ci,build,style,perf: no version bump
When opening a pull request, ensure the PR title itself is a valid Conventional Commit message. The PR title is what release-please consumes when the commits are squash-merged.
Release Process¶
Releases are fully automated via release-please and the Publish Release GitHub
Actions workflow (.github/workflows/release.yml). Maintainers do not need to
manually edit pyproject.toml, tag commits, or push to PyPI.
End-to-end flow¶
Conventional commits land on
mainvia pull requests.On every push to
main, therelease-pleaseaction inspects the commits made since the last release and opens (or updates) a release pull request titledchore(main): release <next-version>. This PR contains:The version bump in
pyproject.toml(under[project] version).The regenerated
CHANGELOG.mdentry, grouped by Conventional Commit type.
While additional commits continue to land on
main,release-pleasecontinuously updates the same release PR — recomputing the proposed version and appending new changelog entries — until it is merged or closed.When a maintainer merges the release PR,
release-pleasecreates a GitHub Release and a correspondingvX.Y.Zgit tag pointing at the merge commit.The release creation triggers the
publishjob in the same workflow, which builds the distribution withpoetry buildand publishes it to PyPI using the PyPI Trusted Publishers mechanism (OIDC; no long-lived API token is stored in the repository).
The Sphinx documentation hosted on Read the Docs is built automatically from the
main branch and from tagged releases.
How version bumps are computed¶
release-please is configured with release-type: python, which follows
Semantic Versioning and derives the next version from the Conventional Commit
types present since the previous tag:
Commit type |
Bump (≥ 1.0.0) |
Notes |
|---|---|---|
|
minor ( |
New, backwards-compatible functionality. |
|
patch ( |
Backwards-compatible bug fix. |
|
major ( |
Any backwards-incompatible change. The |
|
none |
Recorded under “Miscellaneous Chores” / similar sections in the changelog, but do not trigger a release by themselves. |
The highest applicable bump wins: a release containing one feat and one fix
results in a single minor bump.
If the only commits since the last tag are bump-less types (chore, docs,
etc.), release-please will not open a release PR at all. To force a release in
that situation, push a commit using the release-as footer convention, for
example as an empty commit on main:
git commit --allow-empty -m "chore: release 1.2.1" \
-m "Release-As: 1.2.1"
Pre-1.0 behavior¶
While the project version is still 0.x.y, release-please uses a conservative
mapping in accordance with SemVer’s pre-1.0 conventions: breaking changes bump the
minor component, and feat commits bump the patch component. Once the
project ships 1.0.0, the table above applies.
Pre-releases¶
The version declared in pyproject.toml may carry a pre-release suffix (for
example 1.2.0a0) between releases. release-please will strip the pre-release
suffix when computing the next stable release version. Ad-hoc pre-releases (alpha,
beta, rc) are not part of the normal automated flow; if one is needed, cut it
manually by tagging from main and running poetry publish against PyPI from a
trusted environment.
What contributors need to do¶
Write Conventional Commit messages — or, more importantly, ensure the PR title is a valid Conventional Commit, since merges to
mainare squashed and the PR title becomes the commit message thatrelease-pleasereads.Mark backwards-incompatible changes with
feat!/fix!or aBREAKING CHANGE:footer.Do not hand-edit
pyproject.tomlversion,CHANGELOG.md, or create git tags —release-pleaseowns all of these artifacts.