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.3.0.tar.gz (16.3 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.3.0-py3-none-any.whl (24.2 kB view details)

Uploaded Python 3

File details

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

File metadata

  • Download URL: mocklimit-0.3.0.tar.gz
  • Upload date:
  • Size: 16.3 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","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.3.0.tar.gz
Algorithm Hash digest
SHA256 1c2a4e1ace51b00068251acac196837d223f7c6e7f2d7cb61cf76d63ae18a0a1
MD5 5e4f38d078e149466c1a79bd14d27de7
BLAKE2b-256 73c2b8c95dbc14f01e93a6c27f8a6af4a42e3d497294992326cf56a6dbaf5bd8

See more details on using hashes here.

File details

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

File metadata

  • Download URL: mocklimit-0.3.0-py3-none-any.whl
  • Upload date:
  • Size: 24.2 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: uv/0.11.6 {"installer":{"name":"uv","version":"0.11.6","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.3.0-py3-none-any.whl
Algorithm Hash digest
SHA256 472768bfddf9272dd1528fe9e0fa09404ed014aba77f8301b52601357f544c7e
MD5 7f36fbdb8eef84017a7beac14533428e
BLAKE2b-256 b1ba2f4ea399a3bb29b2e86149d0893c1e386e1065e3c3840918f9c23b7782a4

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