Flipython is a self-hosted feature flags service built with FastAPI, SQLAlchemy, Alembic, and PostgreSQL.
It provides a small HTTP API for managing feature flags that can be stored in your own database and evaluated by your application code. The project keeps the domain model separate from the SQLAlchemy model, with a repository layer in between so persistence logic stays isolated from the API.
- Create feature flags
- List feature flags
- Update feature flags
- Delete feature flags
- Protect feature flag routes with bearer token authentication
- Store flags in PostgreSQL through SQLAlchemy
- Manage schema changes with Alembic migrations
- Run locally with Docker Compose and
uv
The service exposes these routes:
GET /health
POST /api-keys
POST /feature-flags
GET /feature-flags
PUT /feature-flags/{flag_id}
DELETE /feature-flags/{flag_id}
Feature flag routes require an authorization header:
Authorization: Bearer <token>
The token is hashed with SHA-256 and matched against enabled API keys stored in the database.
Create an API key record:
curl -X POST http://localhost:8000/api-keys \
-H "Content-Type: application/json" \
-d '{"name": "service-a", "env": "dev"}'Example create request:
curl -X POST http://localhost:8000/feature-flags \
-H "Authorization: Bearer your-api-token" \
-H "Content-Type: application/json" \
-d '{"key": "new-checkout", "enabled": true}'Example response:
{
"id": "00000000-0000-0000-0000-000000000000",
"key": "new-checkout",
"enabled": true
}Example list request:
curl http://localhost:8000/feature-flags \
-H "Authorization: Bearer your-api-token"- Python 3.9+
uv- Docker, for local PostgreSQL
Install dependencies:
uv syncStart PostgreSQL:
docker compose up -dRun database migrations:
uv run alembic upgrade headStart the API:
uv run uvicorn app.main:app --reloadThe API will be available at:
http://localhost:8000
Install or update the project environment:
uv syncRun the API locally:
uv run uvicorn app.main:app --reloadRun migrations:
uv run alembic upgrade headCreate a new Alembic migration:
uv run alembic revision --autogenerate -m "describe migration"Run tests:
uv run pytestRun the linter:
uv run ruff check .Add a runtime dependency:
uv add package-nameAdd a development dependency:
uv add --dev package-nameRemove a dependency:
uv remove package-nameRun a one-off Python command inside the project environment:
uv run python -c "print('hello from flipython')"By default, the application connects to:
postgresql+psycopg://flipython:flipython@localhost:5432/flipython
You can override this with the DATABASE_URL environment variable:
DATABASE_URL=postgresql+psycopg://user:password@host:5432/dbname \
uv run uvicorn app.main:app --reloadapp/
api/ FastAPI route handlers
db/ SQLAlchemy models and session setup
domain/ Domain objects
evaluation/ Feature flag evaluation logic
repositories/ Persistence repositories
migrations/ Alembic migration files
tests/ Automated tests
Before opening a change, run:
uv run pytest
uv run ruff check .