keda-dispatcher
Local dev setup with FastAPI/Redis/S3-compatible storage.
Built-in routes
create_app always includes the built-in /proc routes (see keda_dispatcher/api/proc.py). Passing extra_routers just adds more routers on top; it does not remove the defaults.
Configuration (env vars)
These map directly to keda_dispatcher.settings.Settings:
| Env | Default | Notes |
|---|---|---|
| APP_TITLE | ProcGate | API title |
| APP_VERSION | package __version__ |
API version |
| ENABLE_DOCS | false | Set to true to show Swagger/Redoc |
| ROOT_PATH | (empty) | Prefix for reverse proxies (e.g. /api) |
| HOST | 0.0.0.0 | Uvicorn host |
| PORT | 8080 | Uvicorn port |
| WORKERS | 1 | Uvicorn workers |
| LOG_LEVEL | info | Uvicorn log level |
| RELOAD | false | Uvicorn reload flag |
| REDIS_URL | redis://localhost:6379/0 | Required |
| QUEUE_KEY | queue:jobs | Redis list key for jobs |
| R2_ENDPOINT_URL | (empty) | Cloudflare R2 endpoint |
| R2_ACCESS_KEY_ID | (empty) | R2 access key |
| R2_SECRET_ACCESS_KEY | (empty) | R2 secret key |
| R2_BUCKET | proc-data | R2 bucket |
| EXTRA_API_MODULES | (empty) | Comma-separated pkg.module:router_or_factory list |
CLI flags (e.g. --host, --port, --workers, --log-level, --reload, --extra-router) override env values at startup.
Adding external APIs (APIRouter)
Pass routers via CLI (no env needed):
poetry run keda-dispatcher \
--extra-router myapp.extra:router \
--extra-router myapp.health:get_router \
--host 0.0.0.0 --port 8080
router_or_factorycan be anAPIRouterinstance or a zero-arg factory returning one.--extra-routeris repeatable; values are passed tocreate_appasextra_routers.
Example: start from an external script __main__
Minimal __main__ that injects extra routers and runs uvicorn:
# myservice/__main__.py
import uvicorn
from keda_dispatcher.settings import Settings
from keda_dispatcher.app_factory import create_app
from myapp.api import router as custom_router
from myapp.health import get_router
def main():
settings = Settings.from_env()
extra = [custom_router, get_router()]
app = create_app(settings, extra_routers=extra)
uvicorn.run(app, host=settings.host, port=settings.port, reload=settings.reload)
if __name__ == "__main__":
main()
Run:
python -m myservice
Quick demo
Run:
bash run_demo.sh
Details and code live in tutorials/external_api.md, tutorials/custom_api.py, tutorials/health.py, and run_demo.sh.
Data handling and lifecycle
POST /proc/— issue aprocess_idand store metadata in Redis (status=created).GET /proc/— list processes; optionalstatusfilter.PUT /proc/{id}/dataor/data/json— upload bytes/JSON to R2 atproc/{id}/input; metadata becomesuploaded.POST /proc/{id}/run— enqueue a job into Redis listQUEUE_KEY(defaultqueue:jobs); metadata becomesqueued.DELETE /proc/{id}/queue— remove a queued job for thisprocess_idfrom Redis and reset status (uploadedif data exists, otherwisecreated).GET /proc/{id}/status— returns Redis metadata (status, timestamps, r2_key, etc.).DELETE /proc/{id}/data— delete R2 objectproc/{id}/inputand reset metadata (status=deleted, r2_key/bucket cleared). Process ID remains.DELETE /proc/{id}/kill— mark metadata askilled(does not remove queue entries; workers should honor status).DELETE /proc/{id}— remove R2 object (if present) and delete metadata from Redis. Fails if status isqueuedorrunning.GET /proc/healthz— health check (Redis ping; R2 connectivity if configured).
Note: both binary and JSON uploads share the same R2 key proc/{id}/input, so /data deletion removes either.
Architecture (Mermaid)
flowchart LR
client((Client))
api["FastAPI /proc (keda-dispatcher)"]
redis["Redis meta + queue"]
r2["Cloudflare R2 proc/{id}/input"]
worker["Worker (your impl)"]
keda["KEDA ScaledObject (Redis scaler)"]
client --> api
api -->|metadata| redis
api -->|enqueue| redis
api -->|upload| r2
redis <-. monitor .-> keda
keda -->|scale| worker
worker -->|dequeue/process| redis
worker -->|read input| r2
worker -->|update status| redis
KEDA ScaledObject example
See k8s/keda-scaledobject.yaml for a Redis scaler sample. Key points:
listNamemust matchQUEUE_KEY(defaultqueue:jobs).addressshould point to your Redis service (e.g.,redis.default.svc.cluster.local:6379).- If Redis auth is enabled, set
usernameFromEnv/passwordFromEnvenv vars on the worker Deployment and uncomment in the ScaledObject. scaleTargetRef.nameshould be the Deployment that dequeues jobs.
CI/CD
- Tests:
.github/workflows/test.yml(runs onmain/devand PRs, matrix on Python 3.10–3.12, executespoetry run pytest) - Publish:
.github/workflows/publish.yml(runs on GitHub Releases published event;poetry publish --buildto PyPI) - Publishing needs a repo secret
PYPI_API_TOKEN(a PyPI token likepypi-AgENd...). If the token is missing, publish is skipped with a log message.
Metadata
Release files for keda-dispatcher 0.1.3
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| keda_dispatcher-0.1.3.tar.gz | 16.8 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| keda_dispatcher-0.1.3-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 35.4 kB
Release files / keda_dispatcher-0.1.3.tar.gz
| Download URL | keda_dispatcher-0.1.3.tar.gz |
|---|---|
| Size | 16.8 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
48395ea8eac0cc4e22dba2aee71c36e160d620f94eebd69d996ff81fef4b8203
|
|
BLAKE2b-256 checksum How to use checksums |
71f186590a8e2bc8ced31bc12a9ac3de0d6e294784a9d09d55afb15197ee4167
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.8.3 CPython/3.11.14 Linux/6.11.0-1018-azure
|
Release files / keda_dispatcher-0.1.3-py3-none-any.whl
| Download URL | keda_dispatcher-0.1.3-py3-none-any.whl |
|---|---|
| Size | 18.6 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
1f1ac6ecffb481806ddcb65deeb7d68036ff9c565bbe498787d4608c7a2889a5
|
|
BLAKE2b-256 checksum How to use checksums |
90b510721ef6edb6251206027546d941353e776338dda9bd4e630f06d18e4151
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
poetry/1.8.3 CPython/3.11.14 Linux/6.11.0-1018-azure
|