7.1 KiB
Python-SDK
Status: backlog: Data-Engineering-Use-Cases oder Python-Backend-Integrations für Tenants werden spürbar (mind. 2 Tenant-Anfragen, oder eigener Bedarf in Daten-Pipelines / Notebooks)
Task-ID: #64
Phase: 11 (Backlog)
Estimated Effort: ~1 Woche wenn aktiviert
Owner: unassigned
Problem
Die Boilerplate liefert mit Phase 08 (ts-sdk.md) ein TypeScript-SDK aus, das von Browser-/Node-Konsumenten benutzt werden kann. Tenants mit Python-Stacks (Data-Engineering, Notebooks, FastAPI/Django-Backends, ML-Pipelines, Scraper) müssten heute selbst über requests gegen die OpenAPI-Spec arbeiten. Sobald das spürbar wird (Anfragen, Friction-Reports), lohnt sich ein offizielles, generiertes Python-SDK.
Solange kein Python-Bedarf existiert, ist der Maintenance-Aufwand (Two-SDKs-in-Sync halten, PyPI-Releases bauen, Python-Typing-Edge-Cases) nicht gerechtfertigt.
Depends on
../08-mobile-cli-storybook-sdk/ts-sdk.md— die gleiche OpenAPI-Spec aus dem TS-SDK-Setup ist Quelle der Wahrheit für den Python-Codegen- bestehende OpenAPI-Spec-Generation aus der API-Route-Definition
Blocks
- nichts (Backlog-Item, blockt keine aktive Roadmap)
Approach
Codegen via openapi-generator-cli (Java-basiert, am bequemsten als Docker-Image) gegen die gleiche OpenAPI-Spec wie TS-SDK. Begründung gegen Alternativen:
- Manuell geschriebenes Python-SDK: doppelter Maintenance-Aufwand, drift-anfällig. Verworfen.
- openapi-python-client (Pythonic Codegen): schmaler in Custom-Templates, modernere Typing, aber kleinerer Ökosystem-Support. Sekundär-Option wenn openapi-generator zu verbose ist.
- Custom Codegen via Jinja-Templates: zu viel Eigenentwicklung. Verworfen.
Output: packages/api-client-py/ als PyPI-publishable Package, semver-aligned mit dem TS-SDK (gleiche Major-Version pro API-Version).
Custom-Templates liefern Boilerplate-spezifische Helpers:
- Auth-Handling: API-Key (Header
Authorization: Bearer <key>) und JWT-Bearer, einheitlicher Constructor (Client(api_key=...)oderClient(jwt=...)) - Pagination-Iterator: generierte List-Endpoints geben Python-Iterator zurück, der automatisch über
cursor/pagepaginiert - Retry-Logik: via
tenacitymit Exponential-Backoff + Jitter, nur für 5xx + 429 + Network-Errors - Webhook-Verify: Helper
verify_webhook(secret, payload, signature)mit HMAC-SHA256 (gleiche Signaturlogik wie TS-SDK)
Tests: pytest gegen eine lokal hochgezogene Boilerplate-API (Test-Setup im Repo), Snapshot-Tests für generierten Code (regenerate-Drift erkennen).
Release-Pipeline: GitHub-Actions-Workflow python-sdk-release.yml baut bei Tag-Push (api-client-py-vX.Y.Z) Wheel + sdist und published auf PyPI via Trusted-Publishing (kein PyPI-Token im Repo).
Implementation Steps
- Generator-Setup —
openapi-generator-clials Docker-Image-Pinned-Version inscripts/codegen-python.sh, OpenAPI-Spec wird aus dem laufenden Dev-Server gezogen oder aus dem schon im TS-SDK gespeicherten JSON. Commit:11-backlog/python-sdk: add codegen script - Erstes Codegen-Run — Output in
packages/api-client-py/, Basis-Generator-Output ohne Customizations committen. Commit:11-backlog/python-sdk: initial generated client - Custom-Templates: Auth — Jinja-Templates für Configuration-Class und Auth-Helpers überschreiben, einheitlicher Constructor. Commit:
11-backlog/python-sdk: custom auth templates - Custom-Templates: Pagination — Iterator-Wrapper um List-Endpoints, automatisches Cursor-Following. Commit:
11-backlog/python-sdk: pagination iterator - Retry + Webhook-Verify-Helper —
tenacity-basierter Retry-Decorator,hmac-basierter Webhook-Verifier inapi_client/webhooks.py. Commit:11-backlog/python-sdk: retry + webhook helpers - pytest-Suite gegen lokale API — Dev-Server hochfahren, gegen ein paar key Endpoints testen (List + Pagination, Create, Webhook-Verify, Retry-on-503). Commit:
11-backlog/python-sdk: pytest integration suite - PyPI-Release-Workflow + Doku — GitHub-Actions-Workflow mit Trusted-Publishing,
packages/api-client-py/README.mdmit Quick-Start + Auth-Beispielen + Pagination-Beispiel + Webhook-Verify-Beispiel. Commit:11-backlog/python-sdk: release workflow + readme
Test Requirements
- Unit-Tests: Auth-Header-Setting, Pagination-Iterator (Cursor-Termination, Empty-Response), Retry-Logik (5xx triggert Retry, 4xx nicht), Webhook-Verify (gültig + ungültig + Replay-Toleranz)
- Integration-Tests: gegen lokal hochgezogene Boilerplate-API (Pytest-Fixture startet API + Test-DB) — Create + List + Pagination + Auth-Failure-Cases
- Snapshot-Tests: generierter Code im Repo committed; CI failt wenn Re-Generation ohne Schema-Änderung den Output ändert
- Coverage-Target: ≥80% für Custom-Helpers (Auth, Pagination, Retry, Webhooks); generierter Code ausgenommen
- Test-Files:
packages/api-client-py/tests/
NICHT als completed markieren bevor alle Tests grün sind.
Acceptance Criteria
packages/api-client-py/enthält generiertes Client-Package mit Custom-Auth/Pagination/Retry/Webhook-HelperspytestSuite läuft grün gegen lokale Boilerplate-API- Snapshot-Tests detektieren ungewollten Codegen-Drift
- PyPI-Release-Workflow funktioniert (Dry-Run auf TestPyPI verifiziert)
- README mit Quick-Start + Auth + Pagination + Webhook-Beispielen vorhanden
- Tests grün
- Progress-Log + PROGRESS.md aktualisiert
Rollback Strategy
- Python-SDK ist ein zusätzliches Package — Entfernung beeinträchtigt API nicht
- Bei brüchiger PyPI-Release: alte Version bleibt verfügbar, neue Version yanken via PyPI-Web-UI
- Custom-Templates können stufenweise zurückgenommen werden (z.B. Pagination raus, manueller Cursor wieder); Konsumenten müssen dann auf vorherige Version pinnen
Security Notes
- API-Keys werden nur über Constructor übergeben, nicht aus ENV gelesen — Verantwortung bleibt beim Konsumenten, Logging-Filter verhindert versehentliches Logging des Keys
- Webhook-Verify-Helper verwendet
hmac.compare_digest(timing-safe) statt String-Vergleich - Generierter Code wird auf bekannte CVEs in transitiven Deps gescannt (
pip-auditim CI) - TLS-Verifikation ist Default-On, kein Override-Flag im public API
Subagent Recommendations
- Planning:
Plan-Subagent mitts-sdk.md-Output als Referenz für Feature-Parität - Research:
Explore-Subagent für openapi-generator vs openapi-python-client Vergleich (entscheidet zwischen den beiden falls openapi-generator nicht passt) - Implementation: ein
general-purpose-Subagent pro Step - Tests: separater
general-purpose-Subagent für die Pytest-Suite - Verification:
gsd-verifierfür Acceptance-Criteria - Code-Review:
gsd-code-reviewernach Step 7
Staging-Deployment-Steps
- Branch
agent/11-backlog-python-sdkpushen - Boilerplate-API lokal (oder auf Staging) starten
pip install -e packages/api-client-pyim Test-venv- Manuelles Smoke-Script ausführen (List + Create + Webhook-Verify)
- TestPyPI-Dry-Release vor echtem PyPI-Release
Deviations from Plan
(Wird vom ausführenden Agent gefüllt.)
Progress Log
(Wird vom ausführenden Agent gefüllt.)