Git-backed storage worker for Gitpay Payment Requests.
Each payment request gets an isolated Git repository under the creator user. Every file change is committed and automatically tagged as a sequential release (v1, v2, …). Only the authenticated creator can access their repositories.
| API (local) | http://localhost:3001 |
| Swagger UI | http://localhost:3001/docs |
| ReDoc | http://localhost:3001/redoc |
| OpenAPI | http://localhost:3001/openapi.json |
| Human docs (Jekyll) | docs/ → GitHub Pages |
- Per payment request Git repos — full history, not a blind blob store
- Automatic release tags —
v1,v2, … on every successful commit - ZIP & file download — export the whole tree or a single file at HEAD or a release tag
- User-scoped authentication — service token +
X-User-Id, or per-user API keys; ownership enforced - Stripe-style documentation — guides + API reference (Jekyll / GitHub Pages) linked to live OpenAPI
- Postman + cURL examples — importable collection under
examples/ - Test coverage ≥ 80% — enforced via
pytest-cov(--cov-fail-under=80)
- Python 3.11+
- Git available on
PATH
python -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txt
cp .env.example .env # edit tokens and storage pathPORT=3001
INTERNAL_API_TOKEN=dev-secret
USER_API_KEYS={"user-1":"user-1-secret-key","user-2":"user-2-secret-key"}
GITPAY_REPO_STORAGE_ROOT=./storage/git-repos
GIT_AUTHOR_NAME=Gitpay
GIT_AUTHOR_EMAIL=noreply@gitpay.me| Variable | Purpose |
|---|---|
INTERNAL_API_TOKEN |
Shared secret for service-to-service calls |
USER_API_KEYS |
JSON map user_id → api_key for direct user auth |
GITPAY_REPO_STORAGE_ROOT |
Root directory for on-disk repos |
GIT_AUTHOR_* |
Commit author identity written into each repo |
uvicorn app.main:app --host 0.0.0.0 --port 3001 --reloadTwo modes; both require that the authenticated user matches creator_user_id.
Authorization: Bearer <INTERNAL_API_TOKEN>
X-User-Id: <creator_user_id>Authorization: Bearer <user_api_key>If another user tries to access a repo, the worker returns 403.
Details: docs/guides/authentication.md
| Method | Path | Description |
|---|---|---|
GET |
/health |
Health check |
POST |
/repositories/init |
Create repo + tag v1 |
PUT |
/repositories/file |
Create/update file + next tag |
POST |
/repositories/files |
List tracked files |
POST |
/repositories/read-file |
Read at HEAD / commit / tag (JSON) |
DELETE |
/repositories/file |
Delete file + next tag |
POST |
/repositories/versions |
List release tags |
POST |
/repositories/zip |
Download repo as ZIP (optional tag/commit) |
POST |
/repositories/download-file |
Download one file as attachment |
Mutating responses include commit_sha and version_tag.
Download endpoints return binary bodies with Content-Disposition: attachment and X-Commit-Sha / X-Version-Tag headers.
Interactive reference: run the server and open /docs.
Curated docs: docs/api/.
export BASE=http://localhost:3001
export TOKEN=dev-secret
export USER_ID=user-1
curl -sS -X POST "$BASE/repositories/init" \
-H "Authorization: Bearer $TOKEN" \
-H "X-User-Id: $USER_ID" \
-H "Content-Type: application/json" \
-d '{"creator_user_id":"user-1","payment_request_id":"pr-100"}'Full script: examples/curl/full-flow.sh
- Import
examples/postman/gitpay-worker.postman_collection.json - Optionally import
examples/postman/gitpay-worker.postman_environment.json - Set
baseUrl,token,userId,paymentRequestId - Run Health → Init → Save → List → Read → Versions → Zip → Download file → Delete
You can also import OpenAPI from http://localhost:3001/openapi.json.
Every successful commit is tagged:
init → v1
save → v2
save → v3
delete → v4
Read a historical snapshot with version_tag on /repositories/read-file, or list tags via /repositories/versions.
Guide: docs/guides/versioning.md
$GITPAY_REPO_STORAGE_ROOT/
users/<creator_user_id>/payment-requests/<payment_request_id>/repo/
Human docs live in docs/ (Stripe-style Guides + API Reference, cross-linked).
cd docs
bundle install
bundle exec jekyll serve
# open http://127.0.0.1:4000/gitpay-worker/GitHub Actions workflow .github/workflows/docs.yml builds the Jekyll site and deploys to GitHub Pages on pushes to main that touch docs/.
Enable Settings → Pages → Source: GitHub Actions on the repository.
If the repo name is not gitpay-worker, update baseurl in docs/_config.yml.
| Docs layer | Location |
|---|---|
| How it works / auth / tags | docs/guides/ |
| Endpoint reference | docs/api/ |
| Auto-generated OpenAPI | live /openapi.json, /docs, /redoc |
pytest
# or: pytest -q --cov=app --cov-report=term-missingCoverage is required to stay ≥ 80% (pytest.ini → --cov-fail-under=80). CI runs the same checks (.github/workflows/ci.yml).
app/
main.py # FastAPI app + OpenAPI security schemes
core/ # auth, config, paths, locks, schemas
routes/repositories.py # HTTP endpoints
services/ # git_service, repo_service
docs/ # Jekyll site (GitHub Pages)
examples/
curl/full-flow.sh
postman/ # Collection + environment
tests/ # pytest suite
See LICENSE.