FastAPI microservice that exposes Python functions as REST endpoints. Supports sync and async execution with job tracking, sequential locking, and structured logging. Docker-ready for Cloud Foundry deployment.
├── main.py # App entry point
├── models.py # Pydantic request/response models
├── logging_config.py # Structured logging setup
├── requirements.txt
├── Dockerfile
├── routers/
│ └── routes.py # API endpoints + job dispatcher
└── user_functions/
└── test_functions.py # Registered callable functions
- Client sends a
POSTrequest with the name of the function to run and its parameters. - The server either executes it synchronously (blocks until done) or asynchronously (returns a job ID immediately).
- For async jobs, the client polls
GET /routes/functions/result/{process_id}to retrieve the result. - All tasks share a single
threading.Lock— jobs queue up and run one at a time.
| Method | Path | Description |
|---|---|---|
GET |
/health |
Health check |
POST |
/routes/functions |
Run a function synchronously |
POST |
/routes/functions/async |
Queue a function as a background job |
GET |
/routes/functions/result/{process_id} |
Get the result of a background job |
function_to_run |
Required params |
Description |
|---|---|---|
echo |
text: str, prefix?: str |
Returns text back to the caller |
add_numbers |
numbers: list[float] |
Returns sum and count |
wait |
seconds?: float |
Sleeps for N seconds (simulates a long job) |
get_status |
— | Returns a health payload with timestamp and UUID |
python -m venv venv && source venv/bin/activate
pip install -r requirements.txt
uvicorn main:app --reloadInteractive docs: http://127.0.0.1:8000/docs
docker build -t listener .
docker run -e PORT=8080 -p 8080:8080 listener1. Queue a job (server returns a job ID)
curl -X POST http://localhost:8080/routes/functions/async \
-H "Content-Type: application/json" \
-d '{"function_to_run": "add_numbers", "params": {"numbers": [1, 2, 3]}}'{"message": "Job accepted.", "process_id": "proc_1700000000", "status": "queued"}2. Poll for the result
curl http://localhost:8080/routes/functions/result/proc_1700000000{"process_id": "proc_1700000000", "status": "completed", "result": {"sum": 6.0, "count": 3}, "error": null}- Add your function to
user_functions/(any.pyfile). - Import it in
routers/routes.py. - Register it in the
DISPATCHdict:
DISPATCH: Dict[str, Callable] = {
"my_function": my_function,
...
}Cloud Foundry injects $PORT at runtime automatically. The Dockerfile reads this variable, so no changes are needed.
cf push listener --docker-image <your-registry>/listener:latestNote: Job results are stored in memory. They will be lost if the instance restarts. For persistence, consider adding a database or Redis store.