Endpoint Monitor Service
A typed FastAPI service that stores endpoint monitors in concurrency-safe process memory and runs SSRF-aware on-demand HTTP checks.
Quick start
Requires Python 3.12.
python -m venv .venv
. .venv/bin/activate
pip install -e '.[dev]'
uvicorn app.main:app --reload
OpenAPI is at http://localhost:8000/docs.
curl -s -X POST http://localhost:8000/monitors \
-H 'content-type: application/json' \
-d '{"name":"Example","url":"https://example.com","expected_status":200}'
curl -s -X POST http://localhost:8000/monitors/UUID/check
curl -s http://localhost:8000/monitors/UUID/status
See docs/service-contract.md for routes, schemas, status semantics, error behavior, security,
and architecture.
Configuration
All settings are validated at startup and use the MONITOR_ prefix:
| Variable | Default | Constraint |
|---|---|---|
MONITOR_HOST |
0.0.0.0 |
bind host |
MONITOR_PORT |
8000 |
1..65535 |
MONITOR_LOG_LEVEL |
INFO |
logging level |
MONITOR_CHECK_TIMEOUT_SECONDS |
5 |
>0, <=30 |
MONITOR_MAX_REDIRECTS |
3 |
0..10 |
Quality checks
ruff format --check .
ruff check .
mypy app
pytest
./scripts/verify.sh
Tests use mocked HTTP transports and cover typed CRUD/error behavior, concurrent state changes, status persistence, timeout-safe checking, DNS/private-address blocking, redirect revalidation, and log redaction. No test sends outbound traffic.
Containers
docker build -t endpoint-monitor .
docker run --rm -p 8000:8000 endpoint-monitor
# or
docker compose up --build
The image runs as an unprivileged user, uses one worker, and has a health check.
Important limitation
Storage is deliberately process-local and ephemeral. Restarting loses every monitor. Multiple workers or replicas each have independent data and readiness only establishes that the local process can serve requests. Use one worker; add a shared database before scaling horizontally.