Skip to main content

Instantly generate and run local FastAPI mock servers from JSON schemas

Project description

mock-me ⚡

Instantly generate and run local FastAPI mock servers from JSON schemas — no backend code required.

mock-me start config.json
  ███╗   ███╗ ██████╗  ██████╗██╗  ██╗      ███╗   ███╗███████╗
  ████╗ ████║██╔═══██╗██╔════╝██║ ██╔╝      ████╗ ████║██╔════╝
  ██╔████╔██║██║   ██║██║     █████╔╝  ─── ██╔████╔██║█████╗
  ██║╚██╔╝██║██║   ██║██║     ██╔═██╗      ██║╚██╔╝██║██╔══╝
  ██║ ╚═╝ ██║╚██████╔╝╚██████╗██║  ██╗     ██║ ╚═╝ ██║███████╗
  ╚═╝     ╚═╝ ╚═════╝  ╚═════╝╚═╝  ╚═╝     ╚═╝     ╚═╝╚══════╝
  Instant FastAPI mock servers from JSON – no backend required

Features

  • JSON-first — one config file defines your entire mock API
  • Schema-aware fake data — names, emails, UUIDs, dates, nested objects, arrays
  • All HTTP methods — GET, POST, PUT, PATCH, DELETE
  • Conditional responses — different responses based on path, query, body, or headers
  • Error simulation — probability-based or condition-triggered errors
  • Configurable delays — simulate real-world latency
  • Pagination — automatic pagination envelope wrapping
  • Template strings"ORD-{{int}}", "{{userId}}" reflect request params
  • Hot-reload — watches config file and reloads on change
  • Auto OpenAPI docs — Swagger UI + ReDoc generated automatically
  • Seeded randomness — reproducible fake data across runs
  • Export — generate a standalone FastAPI server.py with no mock-me dependency
  • Plugin system — register custom data generators in Python

Quickstart

Install

pip install mock-me
# or from source:
git clone https://github.com/mock-me/mock-me
cd mock-me && pip install -e .

Create a config

mock-me init --out config.json

Start the server

mock-me start config.json
  mock-me v1.0.0
  ─────────────────────────────────────────
  My API  (dev)
  ─────────────────────────────────────────

  GET     /api/users                   [Users]
  POST    /api/users                   [Users]
  GET     /api/users/{id}              [Users]
  DELETE  /api/users/{id}              [Users]

  Swagger UI → http://localhost:8000/docs
  ReDoc      → http://localhost:8000/redoc
  Health     → http://localhost:8000/__health

  Listening on http://0.0.0.0:8000

Options

mock-me start config.json --port 9000          # override port
mock-me start config.json --host 127.0.0.1     # override host
mock-me start config.json --reload             # watch config for changes
mock-me start config.json --seed 42            # reproducible data

CLI Commands

Command Description
mock-me start config.json Start the mock server
mock-me validate config.json Validate config without starting
mock-me export config.json --out server.py Export a standalone FastAPI server
mock-me init --out config.json Create a starter config file

Config Reference

Top-Level Options

{
  "name": "My API",
  "description": "Optional description",
  "version": "1.0.0",
  "host": "0.0.0.0",
  "port": 8000,
  "environment": "dev",
  "seed": 42,
  "globalDelay": 0.1,
  "globalHeaders": {
    "X-Server": "mock-me"
  },
  "pagination": { ... },
  "plugins": ["./my_plugin.py"],
  "endpoints": [ ... ]
}
Field Type Description
name string Server/API name (shown in Swagger)
port int Port to listen on (default: 8000)
host string Bind host (default: 0.0.0.0)
seed int Random seed for reproducible data
globalDelay float Seconds of delay added to every request
globalHeaders object Headers added to every response
plugins string[] Paths to custom generator plugins

Pagination

"pagination": {
  "defaultPageSize": 10,
  "maxPageSize": 100,
  "pageParam": "page",
  "sizeParam": "size",
  "totalParam": "total",
  "dataParam": "items"
}

When an endpoint has "paginated": true, responses are wrapped:

{
  "items": [...],
  "total": 143,
  "page": 1,
  "size": 10,
  "pages": 15,
  "hasNext": true,
  "hasPrev": false
}

Endpoint Config

{
  "path": "/api/users/{id}",
  "method": "GET",
  "description": "Get a user by ID",
  "tags": ["Users"],
  "delay": 0.2,
  "pathParams": { ... },
  "queryParams": { ... },
  "headerParams": { ... },
  "bodySchema": { ... },
  "response": { ... },
  "conditionalResponses": [ ... ],
  "errors": [ ... ]
}

Field Schemas (Response Body)

Every field in response.body uses a schema:

"fieldName": {
  "type": "string",
  "faker": "email"
}

Supported Types

Type Description Example
string String with optional faker rule {"type":"string","faker":"email"}
int / integer Integer with optional min/max {"type":"int","min":1,"max":100}
float / number Float with optional min/max {"type":"float","min":0.5,"max":9.99}
bool / boolean Random true/false {"type":"bool"}
uuid UUID v4 {"type":"uuid"}
date / datetime ISO datetime string {"type":"date"}
enum Random value from list {"type":"enum","values":["a","b","c"]}
object Nested object {"type":"object","properties":{...}}
array Array of items {"type":"array","items":{...},"minItems":2,"maxItems":5}

Faker Rules

Use a shorthand string or a full rule object:

"email": { "type": "string", "faker": "email" }
"name":  { "type": "string", "faker": "name" }
"bio":   { "type": "string", "faker": { "type": "paragraph" } }

Available faker types:

name, first_name, last_name, email, username, password, phone
address, street, city, state, country, zip
url, domain, ipv4, ipv6, mac
uuid, word, sentence, paragraph, text, slug
company, job, currency, color, hex_color
image_url, iban, ssn, license_plate, user_agent
mime_type, file_name, file_extension, lorem

Static & Template Values

"status":  { "type": "string", "value": "active" }
"orderId": { "type": "string", "template": "ORD-{{int}}" }
"userId":  { "type": "string", "template": "{{userId}}" }

Template variables resolve in this order:

  1. Request path params (e.g. {{userId}}abc123)
  2. Query/body/header params
  3. Faker methods (e.g. {{name}}, {{email}})
  4. Built-ins: {{int}}, {{float}}, {{uuid}}

Nullable Fields

"deletedAt": { "type": "date", "nullable": true }

~10% chance of returning null.


Conditional Responses

Return different responses based on request input. Conditions use dotted paths:

Key prefix Matches
path.userId Path parameter userId
query.status Query param ?status=...
body.email Request body field email
header.x-api-key Request header
"conditionalResponses": [
  {
    "when": { "path.id": "000" },
    "response": {
      "status": 404,
      "body": {
        "error": { "type": "string", "value": "Not found" }
      }
    }
  },
  {
    "when": { "query.role": "admin", "header.x-api-key": "*" },
    "response": {
      "status": 200,
      "body": { "admin": { "type": "bool", "value": true } }
    }
  }
]

Use "*" to check presence (any non-null value).


Error Simulation

"errors": [
  {
    "probability": 0.05,
    "response": {
      "status": 503,
      "body": { "error": { "type": "string", "value": "Service unavailable" } }
    }
  },
  {
    "trigger": { "body.email": "locked@example.com" },
    "response": {
      "status": 403,
      "body": { "error": { "type": "string", "value": "Account locked" } }
    }
  }
]
  • probability — triggers randomly (0.05 = 5% of requests)
  • trigger — triggers when condition matches (same syntax as conditionalResponses.when)

Delays

{
  "globalDelay": 0.05,
  "endpoints": [
    {
      "path": "/api/slow",
      "delay": 2.0,
      "response": {
        "delay": 0.5
      }
    }
  ]
}

Precedence: response.delay > endpoint.delay > globalDelay


Plugin System

Create a Python file with a GENERATORS dict:

# my_plugin.py
import random

def _product_sku():
    return f"SKU-{random.randint(10000, 99999)}"

def _geo_point():
    return {
        "lat": round(random.uniform(-90, 90), 6),
        "lng": round(random.uniform(-180, 180), 6)
    }

GENERATORS = {
    "product_sku": _product_sku,
    "geo_point": _geo_point,
}

Reference in config:

{
  "plugins": ["./my_plugin.py"],
  "endpoints": [{
    "path": "/products",
    "response": {
      "body": {
        "sku":      { "type": "product_sku" },
        "location": { "type": "geo_point" }
      }
    }
  }]
}

Export Standalone Server

Generate a self-contained FastAPI server with zero mock-me dependency:

mock-me export config.json --out server.py

# Run it anywhere:
pip install fastapi uvicorn faker
python server.py

Built-in Endpoints

Path Description
/__health Health check + server metadata
/__config View the parsed config
/docs Swagger UI
/redoc ReDoc documentation
/openapi.json OpenAPI schema

Example: Minimal Config

{
  "name": "Blog API",
  "port": 8000,
  "endpoints": [
    {
      "path": "/posts",
      "method": "GET",
      "tags": ["Posts"],
      "response": {
        "status": 200,
        "paginated": true,
        "body": {
          "id":        { "type": "uuid" },
          "title":     { "type": "string", "faker": "sentence" },
          "content":   { "type": "string", "faker": "paragraph" },
          "author":    { "type": "string", "faker": "name" },
          "published": { "type": "bool" },
          "createdAt": { "type": "date" }
        }
      }
    }
  ]
}

See sample_config.json for a full e-commerce API with 14 endpoints, nested objects, conditionals, errors, and pagination.


Project Structure

mock-me/
├── mock_me/
│   ├── __init__.py     # Package metadata
│   ├── models.py       # Pydantic config schema (ServerConfig, EndpointConfig, etc.)
│   ├── engine.py       # Data engine – fake data generation
│   ├── server.py       # FastAPI app builder – dynamic route registration
│   ├── loader.py       # JSON config loader + hot-reload watcher
│   ├── exporter.py     # Standalone server.py code generator
│   └── cli.py          # CLI entry point (start, validate, export, init)
├── sample_config.json  # Full e-commerce demo (14 endpoints)
├── minimal_config.json # Beginner example
├── example_plugin.py   # Custom generator plugin example
└── pyproject.toml

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

mock_me-1.0.0.tar.gz (20.2 kB view details)

Uploaded Source

Built Distribution

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

mock_me-1.0.0-py3-none-any.whl (20.3 kB view details)

Uploaded Python 3

File details

Details for the file mock_me-1.0.0.tar.gz.

File metadata

  • Download URL: mock_me-1.0.0.tar.gz
  • Upload date:
  • Size: 20.2 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for mock_me-1.0.0.tar.gz
Algorithm Hash digest
SHA256 eb852f4c4b037af5151a48541507f00a2ac8d36c17d90dd6bd08b11fbaf47611
MD5 355cb9c16abaa1e6559f428ba426bbca
BLAKE2b-256 2e3fb9f8592d9be576137b4a9d013406923c1d60be516106c54df132a035c31d

See more details on using hashes here.

File details

Details for the file mock_me-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: mock_me-1.0.0-py3-none-any.whl
  • Upload date:
  • Size: 20.3 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? No
  • Uploaded via: twine/6.2.0 CPython/3.14.4

File hashes

Hashes for mock_me-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 d113cdf7a7239f528ef4b520152c78e3173c5341b7a9a51afb261c805ccce751
MD5 148fa274f82289d85a00eec6ddd46544
BLAKE2b-256 4b37ba8920f5e2660da3f518678137757ac5899f80d6d2c02a40e6b927fa8ca8

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