CI/CD deployment simulator.
From the project root:
python3 -m venv .venv
source .venv/bin/activate # Windows: .venv\Scripts\activate
pip install -r requirements.txtThe API and frontend run on a single server — there is no separate frontend process. FastAPI serves the REST API and static files (App/static/index.html, App/static/styles.css) together.
From the project root, with the virtual environment activated:
uvicorn App.main:app --reload| What | URL |
|---|---|
| Frontend UI | http://127.0.0.1:8000/ |
| API docs (Swagger) | http://127.0.0.1:8000/docs |
| Deployments API | http://127.0.0.1:8000/deployments |
Using the UI
- Open http://127.0.0.1:8000/ in your browser.
- Toggle Deployment generation on to call
POST /deployments/start(adds a deployment every 10 seconds). - Toggle it off to call
POST /deployments/stop. - The deployments table refreshes automatically every 5 seconds via
GET /deployments.
Stop the server with Ctrl+C in the terminal.
Optional flags
# Custom host/port
uvicorn App.main:app --host 0.0.0.0 --port 8080 --reloadApp/models.py defines a Pydantic Deployment record:
| Field | Type | Notes |
|---|---|---|
id |
int | Unique identifier, >= 1 |
service |
literal | billing-api, auth-service, notifications, frontend-web |
status |
literal | running, success, fail, rolled-back (running has duration 0 until completed) |
duration |
float | Duration in seconds |
timestamp |
str | ISO 8601 timestamp |
commit_sha |
str | Git commit SHA (7–40 chars) |
App/deployment_ops.py defines DeploymentOps, an in-memory store backed by a Queue[Deployment]:
add_deployment(deployment)— add a running deployment (status must berunning, duration 0)complete_deployment(deployment_id, status, timestamp)— finalize a running deployment; duration is computed from timestampsread_deployments(service=None, status=None)— list deployments, optionally filteredread_running_deployments(service=None)— list in-flight deploymentsread_deployment(deployment_id)— fetch one deployment by id
App/metric.py defines MetricOps for analytics over completed deployments:
record_completed(deployment)— update per-service stats, status counts, and anomaly detection (called byDeploymentOpson completion)read_anomalies()— list anomalous deploymentssuccess_rate()— success count / total × 100p95_duration()— 95th percentile duration per service
App/dummy_generator.py defines DummyGenerator for synthetic deployment records:
create_dummy_deployment()— build one random runningDeploymentand return it as a dictstart_deployments(ops)— background thread starts a running deployment every 10 seconds and completes them after a simulated durationstop_deployments()— stop the background generator
| Method | Path | Description |
|---|---|---|
| GET | /deployments |
List deployments; optional service, status query filters |
| GET | /deployments/latest |
Latest completed deployments (up to 10) |
| GET | /deployments/running |
All in-flight running deployments; optional service filter |
| GET | /deployments/{id} |
Get one deployment by id (id >= 1) |
| PATCH | /deployments/{id} |
Complete a running deployment (status, timestamp in body) |
| GET | /p95 |
P95 duration per service (or not enough deployments if fewer than 5) |
| GET | /anomalies |
List of anomalous deployments |
| GET | /success-rate |
Success rate percentage { "status": "success", "value": 95.0 } |
| POST | /deployments/start |
Start dummy deployment generation |
| POST | /deployments/stop |
Stop dummy deployment generation |
Errors return a structured body: { "error", "message", "code", "details" }.
App/— application code (main.py, models, static frontend)App/static/—index.html,styles.css- Root —
README.md,.gitignore,requirements.txt