Skip to main content

Per-endpoint cloud cost attribution for Python web apps — see exactly what each API route costs on AWS, GCP, or Azure

Project description

cloudmeter (Python)

Per-endpoint cloud cost monitoring for Python web apps. Supports Flask, FastAPI, and Django — one import, one line.

[Your Flask/FastAPI/Django app]
        │
        │  in-process (zero overhead, no sidecar)
        ▼
[cloudmeter buffer]  →  http://localhost:7777
                     "GET /api/export costs $340/month"

Install

pip install cloudmeter

Zero required dependencies. No sidecar binary. No external process. The cost projector and dashboard run entirely in-process.


Quick start

Flask

from flask import Flask
from cloudmeter.flask import CloudMeterFlask

app = Flask(__name__)
CloudMeterFlask(app, provider="AWS", target_users=1000)

@app.route("/api/users/<int:user_id>")
def get_user(user_id):
    return {"id": user_id}

Open http://localhost:7777 — costs appear as soon as requests hit your app.

FastAPI

from fastapi import FastAPI
from cloudmeter.fastapi import CloudMeterMiddleware

app = FastAPI()
app.add_middleware(CloudMeterMiddleware, provider="AWS", target_users=1000)

@app.get("/api/users/{user_id}")
def get_user(user_id: int):
    return {"id": user_id}

Django — settings.py

MIDDLEWARE = [
    'cloudmeter.django.CloudMeterMiddleware',
    # ... your other middleware
]

CLOUDMETER = {
    "provider":     "AWS",
    "region":       "us-east-1",
    "target_users": 1000,
}

Configuration options

All options are optional — defaults work out of the box.

Option Default Description
provider "AWS" Cloud provider: "AWS", "GCP", or "AZURE"
region "us-east-1" Cloud region (e.g. "us-central1", "eastus")
target_users 1000 Concurrent users to project cost at
requests_per_user_per_second 1.0 Scaling factor for the projection
budget_usd 0.0 Monthly budget alert per endpoint (0 = off)
port 7777 Port for the live cost dashboard

Flask — app factory pattern

from cloudmeter.flask import CloudMeterFlask

cm = CloudMeterFlask()

def create_app():
    app = Flask(__name__)
    cm.init_app(app, provider="GCP", region="us-central1", target_users=5000)
    return app

FastAPI — full options example

app.add_middleware(
    CloudMeterMiddleware,
    provider="AWS",
    region="eu-west-1",
    target_users=50_000,
    budget_usd=200.0,
)

Django — full options in settings.py

CLOUDMETER = {
    "provider":                     "AZURE",
    "region":                       "eastus",
    "target_users":                 2000,
    "requests_per_user_per_second": 2.0,
    "budget_usd":                   500.0,
}

Dashboard panels

Open http://localhost:7777 after starting your app:

Panel What it shows
Cost table Each route with projected monthly cost, cost per user, recommended instance
Cost curve Cost vs concurrent-user count chart (100 → 1M users) for any selected route
Variance panel p50/p95/p99 per-request cost; p95/p50 > 1.5× flags N+1 queries or missing indexes
Recording controls Start/stop metric collection; first 30 s is warmup (excluded from projections)

How route templates work

CloudMeter reports route templates, not raw paths — so all traffic to /api/users/1, /api/users/42, and /api/users/999 is grouped as a single endpoint with a single cost projection.

Framework Template source Example
Flask request.url_rule GET /api/users/<int:user_id>
FastAPI scope["route"].path GET /api/users/{user_id}
Django request.resolver_match.route GET api/users/<int:pk>/

What's measured

For each request:

  • Route template — not the raw URL
  • HTTP method — GET, POST, etc.
  • HTTP status code — 200, 404, 500, etc.
  • Wall-clock duration — in milliseconds
  • Response size — egress bytes (from Content-Length header)

CPU accuracy note: Python cannot attribute per-request CPU time because of the GIL. Wall-clock time is used as a proxy. Cost accuracy is ±40% vs the Java agent's ±20%. Egress and instance selection are not affected.


Privacy and security

  • Request and response bodies are never captured — only route, method, status, duration, and byte counts
  • The dashboard binds to 127.0.0.1 only — not reachable from outside the host
  • No authentication on the dashboard — do not expose port 7777 publicly
  • No cloud credentials ever required — pricing uses static embedded tables

Running tests

pip install pytest pytest-asyncio httpx flask "fastapi[standard]" django
cd clients/python
pytest tests/ -v

86 tests covering Flask, FastAPI, Django middleware, the reporter buffer, cost projector, and dashboard server.


Troubleshooting

Dashboard shows no data: Make sure your app is receiving real HTTP requests (or use its test client). Endpoints only appear after they have been hit.

First 30 seconds shows "warmup excluded": Normal — the first 30 s after recording starts are excluded to avoid JIT/cold-start noise inflating cost projections. Data will appear automatically after warmup.

Port conflict (Address already in use): Change the dashboard port:

CloudMeterFlask(app, port=17777)

License

Apache 2.0 — see LICENSE at the repository root.

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

cloudmeter-0.5.0.tar.gz (20.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

cloudmeter-0.5.0-py3-none-any.whl (13.6 kB view details)

Uploaded Python 3

File details

Details for the file cloudmeter-0.5.0.tar.gz.

File metadata

  • Download URL: cloudmeter-0.5.0.tar.gz
  • Upload date:
  • Size: 20.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for cloudmeter-0.5.0.tar.gz
Algorithm Hash digest
SHA256 1bd1c72b395bed481e69a00b0fd037729ac756bbaad719b3d185c5f9c426a4ad
MD5 3fc11995d665fedbcd5f648ddb752894
BLAKE2b-256 e79c150d297b8e07f77ff385b171ae1025b5da8071e2a2d201037af8d87d2da2

See more details on using hashes here.

File details

Details for the file cloudmeter-0.5.0-py3-none-any.whl.

File metadata

  • Download URL: cloudmeter-0.5.0-py3-none-any.whl
  • Upload date:
  • Size: 13.6 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.12.13

File hashes

Hashes for cloudmeter-0.5.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f157704d70d9b61a5e91666ef308ac1710e172395e877e0ea59b0f9e7b45cac6
MD5 598a285ebb5ecbb951e623f1bb2aee13
BLAKE2b-256 8fc54b59d0069756cd28c3802a7ad2e7bd4f4dcacf0d0e70824ad389ffef7cb0

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page