Development¶
Common tasks¶
A justfile wraps the common operations:
just # list all recipes
just sync # uv sync
just lint # ruff check (generated/ is excluded)
just typecheck # ty check (generated/ is excluded)
just test # pytest
just check # lint + typecheck + test — what CI runs
just build # build the sdist/wheel and verify generated/ made it into the wheel
just fetch-specs # download OpenAPI specs into specs/
just generate # regenerate Kiota clients from specs/ (needs Docker)
just fetch-specs and just generate both accept an optional list of
service names to limit the operation, e.g. just generate annosaurus oni.
Regenerating clients¶
vars_client.generated is produced by Kiota
and must never be hand-edited. scripts/services.conf is the single source
of truth mapping each service to its spec-URL environment variable and Kiota
class name — add a row there to onboard a new service.
export ANNOSAURUS_SPEC_URL=https://annosaurus.example.org/openapi.yaml
# ... one *_SPEC_URL per service you want to (re)fetch
just fetch-specs # downloads specs/*.yaml
just generate # runs Kiota via Docker, writes src/vars_client/generated/<service>/
vars_client.generated.__init__ hand-maintains convenience re-exports
(from vars_client.generated import AnnosaurusClient, etc.) — Kiota only
writes into the per-service subdirectories, so this file is safe from being
clobbered by regeneration.
Testing¶
Tests live under tests/, using pytest + pytest-asyncio + respx to
mock HTTP at the transport layer — no real VARS deployment needed. See
tests/auth/ and tests/test_client.py for the patterns used to test the
JWT exchange/refresh flows and end-to-end client wiring.
CI¶
.github/workflows/ci.yml runs just lint, just typecheck, just test,
and a just build + wheel-content check on every push/PR to main. It
can't reach VARS' internal OpenAPI spec URLs, so spec regeneration isn't
part of CI — run just fetch-specs && just generate locally when upstream
specs change, and commit the diff.
Docs¶
This site is itself built with Zensical:
just docs-generate # regenerate docs/reference/ from specs/ + generated/
just docs-serve # live preview at localhost:8000 (runs docs-generate first)
just docs-build # build to site/ (runs docs-generate first)
The API Reference pages (docs/reference/) aren't hand-written or
committed — scripts/gen_api_reference.py generates them from
specs/*.yaml cross-referenced against the real generated Kiota code, so
they can't drift from either. See Exploring the API
for what that output looks like and why it's built this way.
.github/workflows/docs.yml builds and deploys it to GitHub Pages via the
actions/deploy-pages action on every push to main.
Releasing¶
Versioning is automated with python-semantic-release,
driven entirely by Conventional Commits
on main (stable) and develop (prerelease, -rc.N suffix) — nothing to do
by hand beyond writing properly-typed commit messages. feat: bumps minor,
fix:/perf: bump patch, a BREAKING CHANGE: footer bumps major (even pre-1.0,
since major_on_zero = true).
The release job in .github/workflows/ci.yml runs after test/build
pass on a push to main/develop: it bumps project.version and
vars_client.__version__, updates CHANGELOG.md, tags and pushes the
commit, cuts a GitHub release, and — for a non-prerelease version — builds
and publishes to PyPI. Requires a PYPI_TOKEN repo secret; the tagging/release
steps use the default GITHUB_TOKEN.