Skip to main content

Configurable mock API server with realistic rate limiting for testing

Project description

mocklimit

CI PyPI Python License: MIT

Configurable mock API server with realistic rate limiting for testing. Point it at an OpenAPI spec, define rate limit policies in YAML, and get a local server that behaves like a rate-limited production API, complete with correct headers, 429 responses, and token usage estimation.

Features

  • OpenAPI spec auto-routing - parses your spec and registers all endpoints with dummy responses
  • Fixed window rate limiting with sub-second precision
  • Quantized rate limiter for aligned reset windows
  • Composite limits - stack multiple limits per endpoint (e.g. RPM + TPM)
  • Provider-accurate headers - configurable header names (x-ratelimit-limit-requests, etc.)
  • Token usage estimation for LLM API mocking
  • Configurable response latency simulation
  • Per-key scoping by API key or IP address
  • Request statistics via /mocklimit/stats
  • Prometheus metrics at /metrics -- request counts, latency histograms, rate limit gauges

Installation

pip install mocklimit

Or with uv:

uv add mocklimit

Quick start

1. Create a rate limit config

# limits.yaml
policies:
  openai_chat:
    strategy: fixed_window
    limits:
      - max_requests: 5
        window_seconds: 60
    scope: api_key
    response_latency_ms: [0, 0]
    headers:
      limit: x-ratelimit-limit-requests
      remaining: x-ratelimit-remaining-requests
      reset: x-ratelimit-reset-requests

endpoints:
  /chat/completions:
    methods: [POST]
    policy: openai_chat
    token_estimation:
      input: characters_div_4
      output: [50, 500]

2. Start the server

mocklimit serve --spec openapi.yaml --rate-config limits.yaml

The server reads your OpenAPI spec for route definitions and response schemas, then applies rate limiting according to the config. Requests beyond the limit get a 429 with appropriate Retry-After and rate limit headers.

3. Options

mocklimit serve --spec <path> --rate-config <path> [--host HOST] [--port PORT]
Flag Default Description
--spec (required) Path to OpenAPI spec (YAML)
--rate-config (required) Path to rate limit config (YAML)
--host 127.0.0.1 Host to bind to
--port 8000 Port to listen on

Rate limit config reference

Policies

Each policy defines a rate limiting strategy:

Field Type Description
strategy "fixed_window" Rate limiting algorithm
limits list One or more {max_requests, window_seconds} pairs
scope "api_key" | "ip" How to identify clients
response_latency_ms [min, max] Simulated response delay range (ms)
headers.limit string Header name for the request limit
headers.remaining string Header name for remaining requests
headers.reset string Header name for reset time

Endpoints

Map API paths to policies:

Field Type Description
methods list of strings HTTP methods to rate limit
policy string Name of the policy to apply
token_estimation object (optional) {input: "characters_div_4", output: [min, max]}

Prometheus metrics

mocklimit exposes a Prometheus-compatible scrape endpoint at /metrics/.

Exposed metrics

Metric Type Labels Description
mocklimit_requests_total Counter endpoint, method, scope_key, status Total requests to rate-limited endpoints
mocklimit_rate_limited_total Counter endpoint, method, scope_key Requests denied with 429
mocklimit_request_duration_seconds Histogram endpoint, method, status Handler latency including simulated delay
mocklimit_rate_limit_remaining Gauge endpoint, policy, scope_key Remaining requests in the current window

Prometheus scrape config

scrape_configs:
  - job_name: mocklimit
    metrics_path: /metrics/
    static_configs:
      - targets: ["localhost:8000"]

Example output

After a few requests:

mocklimit_requests_total{endpoint="POST /chat/completions",method="POST",scope_key="my-key",status="200"} 5.0
mocklimit_requests_total{endpoint="POST /chat/completions",method="POST",scope_key="my-key",status="429"} 1.0
mocklimit_rate_limited_total{endpoint="POST /chat/completions",method="POST",scope_key="my-key"} 1.0
mocklimit_rate_limit_remaining{endpoint="POST /chat/completions",policy="chat",scope_key="my-key"} 0.0
mocklimit_request_duration_seconds_count{endpoint="POST /chat/completions",method="POST",status="200"} 5.0

Programmatic usage

You can also embed the server directly in tests:

from mocklimit.server import create_app

app = create_app("openapi.yaml", "limits.yaml")

This returns a standard FastAPI app that can be used with any ASGI test client.

License

MIT

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

mocklimit-0.4.0.tar.gz (17.2 kB view details)

Uploaded Source

Built Distribution

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

mocklimit-0.4.0-py3-none-any.whl (25.9 kB view details)

Uploaded Python 3

File details

Details for the file mocklimit-0.4.0.tar.gz.

File metadata

  • Download URL: mocklimit-0.4.0.tar.gz
  • Upload date:
  • Size: 17.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for mocklimit-0.4.0.tar.gz
Algorithm Hash digest
SHA256 9f388856e0e89f2e0ce1d461d2fa4ab3f6892a05658e0c47e56a291a43917df7
MD5 c96083c72709574e91566ee2b7311d49
BLAKE2b-256 c33bc956e853254bd463e1233d7a476ba4204d1f932061ba5e2de63898b0f870

See more details on using hashes here.

File details

Details for the file mocklimit-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: mocklimit-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 25.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.7 {"installer":{"name":"uv","version":"0.11.7","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}

File hashes

Hashes for mocklimit-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 342a9a28e22199bd823f894c8abdd8bb80f27769953eb1329f14a81da2d2fc5c
MD5 2229b6f5ae3952cb9971b43528ef0e80
BLAKE2b-256 7ec433c7c202e280fbb4c192ff0038cea7a6a8038dea6bfdf7fae49f35d38229

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