🐮 fastapi-calf 🐮
fastapi-calf is a lightweight terminal monitor for FastAPI applications. It
shows live route activity, request counts, failures, latency, requests per
second, CPU and memory use, and worker process information.
Monitoring is best-effort. The application sends small events to the dashboard over TCP with a short timeout; an unavailable dashboard does not stop requests from being served.
Requirements
- Python 3.10 or newer
richandpsutilfor the monitoring package- FastAPI and an ASGI server such as Uvicorn in the application being monitored
FastAPI is intentionally not installed as a dependency of fastapi-calf. This
keeps the monitoring package small and allows the application to manage its own
FastAPI version.
Installation
Install the package from the repository:
python -m pip install .
For local development, use an editable install:
python -m pip install -e .
The application environment must provide FastAPI and an ASGI server:
python -m pip install fastapi uvicorn
Installing the package creates the calf command.
Quick start
1. Add the middleware
Create or update the FastAPI application:
from fastapi import FastAPI
from fastapi_calf import Calf
app = FastAPI()
# The dashboard started in the next step listens on this port.
Calf.listen(app, host="127.0.0.1", port=8765)
@app.get("/health")
def health():
return {"status": "ok"}
Call Calf.listen once, after creating the application. The middleware records
all HTTP routes, so individual route decorators are not required.
2. Start the dashboard
In one terminal, run:
calf --port 8765
The equivalent module command is:
python -m fastapi_calf.daemon --port 8765
3. Start the API
In another terminal, run the application:
python -m uvicorn app:app --host 127.0.0.1 --port 8000
Requests to http://127.0.0.1:8000 now appear in the dashboard.
Production example
The middleware supports multiple Uvicorn workers. Start the dashboard first, then start the application:
calf --port 8765
python -m uvicorn app:app --host 0.0.0.0 --port 8000 --workers 4
Each worker reports its PID, CPU use, memory use, request count, and the value
of CUDA_VISIBLE_DEVICES when that environment variable is set.
The monitor is an operational display, not a durable metrics store. Run it under a process supervisor such as systemd, Supervisor, or your container orchestrator when it needs to remain available.
Configuration
Calf.listen accepts the following arguments:
Calf.listen(app, host="127.0.0.1", port=8765)
| Argument | Default | Purpose |
|---|---|---|
app |
required | FastAPI application on which the HTTP middleware is registered |
host |
127.0.0.1 |
Address used by the application to connect to the dashboard |
port |
required | TCP port used for monitoring events |
The port passed to Calf.listen must match the dashboard's --port value. It
is independent of the HTTP port used by Uvicorn.
The current dashboard binds to 127.0.0.1. The API and dashboard therefore
need to run on the same machine or in the same network namespace. In separate
containers, 127.0.0.1 points to different containers, so this release needs
both processes in one container/pod network namespace to communicate.
Optional route decorator
@lookout provides per-route instrumentation when the global middleware is not
being used. The endpoint must accept a FastAPI Request parameter named
request:
from fastapi import FastAPI, Request
from fastapi_calf import lookout
app = FastAPI()
@app.post("/jobs")
@lookout
async def create_job(request: Request):
payload = await request.json()
return {"accepted": True, "job": payload}
Configure the destination before using decorator-only instrumentation if the
dashboard is not using the default 127.0.0.1:8765 destination:
from fastapi_calf.config import config
config.host = "127.0.0.1"
config.port = 9000
Do not apply @lookout to a route already covered by Calf.listen; doing so
sends two events for one request and inflates the displayed metrics.
What the dashboard reports
- Endpoint and HTTP method
- Total and failed request counts
- Average and most recent latency
- Most recent HTTP status
- Rolling latency and requests-per-second sparklines
- CPU and memory use across application workers
- Per-worker PID, resource use, request count, and GPU assignment
Worker statistics are collected from local operating-system process IDs. This is another reason the dashboard should run alongside the monitored application.
Operational behavior
- Event delivery uses a TCP connection to the configured dashboard for each request.
- Connection failures and timeouts are caught so monitoring cannot terminate an API request.
- Events are processed in memory and are not retained after the dashboard exits.
- The dashboard port carries monitoring data and should not be exposed publicly.
- Request bodies are not captured by the global middleware.
- High-volume deployments should load-test the monitoring overhead before enabling it in production.
Troubleshooting
No requests appear
Confirm that the dashboard is running, the two port values match, and
Calf.listen(app, ...) is called on the same application object served by
Uvicorn.
The application logs connection errors
The dashboard is unavailable or listening on a different port. Start calf
before the API or correct the host and port configuration. These errors do not
stop the API from serving traffic.
Worker CPU or memory is missing
The dashboard must be able to inspect the application's local process IDs. Run the dashboard under the same operating-system user and in the same host or pod as the API workers.
Development and tests
Install the additional test dependencies and run pytest:
python -m pip install -r requirements-test.txt
python -m pytest
License and stability
This is an early-stage project intended for experiments, internal tools, ML pipelines, and proofs of concept. Review and load-test it before use on a latency-sensitive production service.
Release files for fastapi-calf 0.1.2
For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.
Source distribution (sdist)
| File | Size | Uploaded | |
|---|---|---|---|
| fastapi_calf-0.1.2.tar.gz | 11.7 kB | Details |
Built distribution (wheel)
| File | Interpreter | ABI | Platform | Reset |
|---|---|---|---|---|
| fastapi_calf-0.1.2-py3-none-any.whl | Python 3 | none | any | Details |
Total release size: 23.5 kB
Release files / fastapi_calf-0.1.2.tar.gz
| Download URL | fastapi_calf-0.1.2.tar.gz |
|---|---|
| Size | 11.7 kB |
| Tags | Source |
|
SHA-256 checksum How to use checksums |
d15d1fd2c5cc625acff7408a6e01f066dd5f52656b260f05c54cbce1b0a0a5af
|
|
BLAKE2b-256 checksum How to use checksums |
f8f8bf3f5fb40655228b1b78d61414636d9022f835cb35a11e377df0f726a644
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|
Release files / fastapi_calf-0.1.2-py3-none-any.whl
| Download URL | fastapi_calf-0.1.2-py3-none-any.whl |
|---|---|
| Size | 11.8 kB |
| Tags | Python 3 |
|
SHA-256 checksum How to use checksums |
52e4a8f92f857c4e994671008569b15d2465b767e10769b88d517ec904892a7b
|
|
BLAKE2b-256 checksum How to use checksums |
9e9d7d8d8a99efb94d1b52c9fd73a98b1d50991e1fccc8d1e471e63a9c66ba93
|
| Upload date | |
|
Uploaded using Trusted Publishing? What is trusted publishing? |
No |
| Uploaded via |
twine/7.0.0 CPython/3.12.3
|