Thanks for your interest in contributing to the official Python SDK for Ferro Labs AI Gateway. This document explains how to propose changes, set up your environment, and get your pull request merged.
By participating in this project you agree to uphold our Code of Conduct. Please report unacceptable behavior to hello@ferrolabs.ai.
- Report bugs. Open an issue with a minimal reproduction, the SDK version, Python version, and the gateway version you are targeting.
- Propose features. Open an issue describing the use case before sending a PR for anything non-trivial — it saves everyone time.
- Improve docs. Typos, clarifications, and new examples are always welcome.
- Fix issues. Look for issues labeled
good first issueorhelp wanted.
Requires Python 3.9 or newer.
git clone https://github.com/ferro-labs/ferrolabs-python-sdk.git
cd ferrolabs-python-sdk
python -m venv .venv
source .venv/bin/activate
make installmake install installs the package in editable mode with the dev extras (pytest, mypy, ruff).
| Command | Purpose |
|---|---|
make install |
Install the package in editable mode |
make format |
Format code with ruff |
make lint |
Run ruff and mypy |
make test |
Run the pytest suite |
make build |
Build the sdist and wheel |
make clean |
Remove build artifacts and tool caches |
Run make format lint test before every commit.
- Python 3.9+ syntax. Use
dict[str, X],X | None, andfrom __future__ import annotationsin new modules. - Type annotations are required on every public function, method, and class attribute.
mypy --strictmust pass. - Ruff handles both linting and formatting. Do not hand-format — run
make format. - Keep files small. Prefer several focused modules over one large file.
- Immutability by default. Do not mutate arguments; return new objects.
- No hardcoded secrets in code, tests, or fixtures.
- Every bug fix needs a regression test.
- Every new feature needs unit tests, and integration tests when it touches the HTTP layer.
- Use
pytest-httpxto mock gateway responses — do not hit real providers in tests. - Target 80%+ coverage on new code.
Run the suite with:
make testFollow Conventional Commits:
<type>: <short description>
<optional body explaining the "why">
Types: feat, fix, refactor, docs, test, chore, perf, ci.
Keep the subject line under 72 characters. Explain the motivation in the body when the change is not obvious.
- Fork the repo and create a feature branch off
development. - Make focused commits — one logical change per commit where practical.
- Run
make format lint testlocally. - Update
CHANGELOG.mdunder theUnreleasedsection. - Open a PR against
developmentwith:- A clear description of what changed and why.
- Links to related issues.
- A short test plan showing what you verified.
- Ensure CI passes. Address review feedback promptly.
PRs are squash-merged by default. Keep them reviewable — split large changes into smaller PRs when possible.
Releases are cut from main. Maintainers handle version bumps, tagging, and PyPI publication. If a change requires a release, mention it in the PR description.
- Open a GitHub Discussion for design questions.
- Open an issue for bugs and feature requests.
- Email
hello@ferrolabs.aifor anything that needs a private channel.