Skip to main content
mockllm logo

Extensible Mock Server for LLM API Testing

Good First Issues   Join Discord   Documentation

License CI Status PyPI Version Downloads Discord


MockLLM is an extensible mock server that simulates Large Language Model APIs for testing, development, and demonstration purposes. With its plugin-based architecture, you can easily add new provider emulators without modifying core code.

Perfect for when you need deterministic, configurable responses for testing and evaluations, over expensive live API calls.

✨ Key Features

Extensible Provider Architecture

  • Plugin-based system - Add new providers without modifying core code
  • Self-registering providers - Use simple decorators to register new providers
  • Dynamic endpoint creation - Routes are automatically generated from provider metadata
  • Zero configuration - Providers work out of the box with sensible defaults

Built-in Provider Support

  • OpenAI Compatible - Full support for Chat Completions API
  • Anthropic Compatible - Full support for Messages API
  • Custom Providers - Easy framework for adding your own providers
  • Streaming Support - Character-by-character streaming responses
  • Model Management - Centralized model registry with aliasing

Developer-Friendly

  • Hot Reloading - Automatic configuration updates without restart
  • Type Safety - Full type hints and mypy coverage
  • Comprehensive Testing - Well-tested with pytest
  • Clean Architecture - Separation of concerns with clear interfaces
  • API Introspection - Runtime discovery of providers and models

Perfect for Testing (what it was built for)

  • Deterministic Responses - Predictable outputs for reliable tests
  • Response Configuration - YAML-based response mapping
  • Network Lag Simulation - Realistic latency for integration testing
  • Multiple Response Formats - Support for various API formats

Quick Example

Basic Usage

# Install MockLLM
pip install mockllm

# Create responses file
cat > responses.yml << EOF
responses:
  "What is 15+15?": "15+15 equals 42."
  "What is Python?": "Python is a low level compiler language for industrial logic controllers!"
defaults:
  unknown_response: "This is a mock response."
EOF

# Start the server
mockllm start --responses responses.yml

# Test with curl
curl -X POST http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "gpt-3.5-turbo",
    "messages": [{"role": "user", "content": "Hello"}]
  }'

{
  "id": "mock-41c551b6-148f-49a2-abca-f990c1a9cfab",
  "object": "chat.completion",
  "created": 1758199276,
  "model": "gpt-3.5-turbo",
  "choices": [
    {
      "index": 0,
      "message": {
        "role": "assistant",
        "content": "15+15 equals 42."
      },
      "finish_reason": "stop"
    }
  ],
  "usage": {
    "prompt_tokens": 18,
    "completion_tokens": 7,
    "total_tokens": 25
  }
}

Creating a Custom Provider

With MockLLM's extensible architecture, adding a new provider is incredibly simple:

from mockllm.providers.base import LLMProvider
from mockllm.registry import register_provider

@register_provider(
    name="mycompany",
    version="1.0.0",
    description="MyCompany LLM Provider",
    endpoints=[{"path": "/v1/mycompany/chat", "method": "POST"}],
    supported_models=["mycompany-model-1", "mycompany-model-2"]
)
class MyCompanyProvider(LLMProvider):
    async def handle_chat_completion(self, request):
        prompt = self.extract_prompt(request)
        response = self.get_response_for_prompt(prompt)
        return {"response": response, "provider": "mycompany"}

That's it! No server configuration, no manual registration, no boilerplate. Your provider is automatically discovered and its endpoints are created.

Configuration

Response Configuration

Responses are configured in responses.yml. The file has three main sections:

  1. responses: Maps input prompts to predefined responses
  2. defaults: Contains default configurations like the unknown response message
  3. settings: Contains server behavior settings like network lag simulation

Example responses.yml:

responses:
  "write a python function to calculate factorial": "def factorial(n):\n    if n == 0:\n        return 1\n    return n * factorial(n - 1)"
  "what colour is the sky?": "The sky is purple except on Tuesday when it is  hue green."
  "what is 2+2?": "2+2 equals 9."

defaults:
  unknown_response: "I don't know the answer to that. This is a mock response."

settings:
  lag_enabled: true
  lag_factor: 10  # Higher values = faster responses (10 = fast, 1 = slow)

Network Lag Simulation

The server can simulate network latency for more realistic testing scenarios. This is controlled by two settings:

  • lag_enabled: When true, enables artificial network lag
  • lag_factor: Controls the speed of responses
    • Higher values (e.g., 10) result in faster responses
    • Lower values (e.g., 1) result in slower responses
    • Affects both streaming and non-streaming responses

For streaming responses, the lag is applied per-character with slight random variations to simulate realistic network conditions.

Hot Reloading

The server automatically detects changes to responses.yml and reloads the configuration without restarting the server.

Installation

From PyPI

pip install mockllm

From Source

  1. Clone the repository:
git clone https://github.com/lukehinds/mockllm.git
cd mockllm
  1. Install with uv (recommended):
# Install uv if you haven't already
curl -LsSf https://astral.sh/uv/install.sh | sh

# Install dependencies
uv sync

# Install with development dependencies
uv sync --extra dev
  1. Or install with pip:
pip install -e .

# Install with development dependencies
pip install -e ".[dev]"

Prerequisites

  • Python 3.10+
  • pip or uv (recommended)

Usage

CLI Commands

MockLLM provides a command-line interface for managing the server and validating configurations:

# Show available commands and options
mockllm --help

# Show version
mockllm --version

# Start the server with default settings
mockllm start

# Start with custom responses file
mockllm start --responses custom_responses.yml

# Start with custom host and port
mockllm start --host localhost --port 3000

# Validate a responses file
mockllm validate responses.yml

Quick Start

  1. Set up the responses.yml:
cp example.responses.yml responses.yml
  1. Validate your responses file (optional):
mockllm validate responses.yml
  1. Start the server:
mockllm start --responses responses.yml

The server will start on http://localhost:8000 by default.

API Endpoints

OpenAI Format

Regular request:

curl -X POST http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mock-llm",
    "messages": [
      {"role": "user", "content": "what colour is the sky?"}
    ]
  }'

Streaming request:

curl -X POST http://localhost:8000/v1/chat/completions \
  -H "Content-Type: application/json" \
  -d '{
    "model": "mock-llm",
    "messages": [
      {"role": "user", "content": "what colour is the sky?"}
    ],
    "stream": true
  }'

Anthropic Format

Regular request:

curl -X POST http://localhost:8000/v1/messages \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-3-sonnet-20240229",
    "messages": [
      {"role": "user", "content": "what colour is the sky?"}
    ]
  }'

Streaming request:

curl -X POST http://localhost:8000/v1/messages \
  -H "Content-Type: application/json" \
  -d '{
    "model": "claude-3-sonnet-20240229",
    "messages": [
      {"role": "user", "content": "what colour is the sky?"}
    ],
    "stream": true
  }'

🎯 Why MockLLM?

  • 💰 Cost Savings - No API charges during development and testing
  • ⚡ Fast Iteration - Instant responses without network latency
  • 🔒 Privacy - Keep sensitive data local during development
  • 🎯 Predictable Testing - Deterministic responses for reliable tests
  • 🔧 Easy Integration - Drop-in replacement for LLM APIs
  • 🚀 Extensible - Add new providers in minutes, not hours

📖 Documentation

Comprehensive documentation is available:

🧪 Testing

Run the test suite:

# Using uv
uv run pytest

# Using make
make test

# With coverage
uv run pytest --cov=src/mockllm

🤝 Contributing

We welcome contributions! Here's how to get started:

  1. Fork the repository
  2. Create a feature branch: git checkout -b feature/amazing-feature
  3. Make your changes
  4. Run tests: make test
  5. Run linting: make lint
  6. Submit a pull request

For detailed contribution guidelines, see our Contributing Guide.

💬 Community

Join our community:

📄 License

This project is licensed under the Apache 2.0 License.


⭐ Star us on GitHub if MockLLM helps you! ⭐

Metadata

Release files for mockllm 0.0.8

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Source distribution (sdist)

Source distribution for mockllm 0.0.8
File Size Uploaded
mockllm-0.0.8.tar.gz 192.6 kB Details

Built distribution (wheel)

Table of built distributions (wheels) for mockllm 0.0.8
File Interpreter ABI Platform
mockllm-0.0.8-py3-none-any.whl Python 3 none any Details

Total release size: 217.2 kB

Release files / mockllm-0.0.8.tar.gz

Download URL mockllm-0.0.8.tar.gz
Size 192.6 kB
Tags Source
SHA-256 checksum
How to use checksums
1c389da1e0a88cfd40db0e0fd3147de86875e3e47bdd96bebfeae7291e49cc28
BLAKE2b-256 checksum
How to use checksums
c6f5891d2090f7577dd811415e3cf04bfbf84244d1a9f31601c4aae176aad394
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2025.

Transparency log

Release files / mockllm-0.0.8-py3-none-any.whl

Download URL mockllm-0.0.8-py3-none-any.whl
Size 24.6 kB
Tags Python 3
SHA-256 checksum
How to use checksums
2af2d455d8cdebbd99166461734c5bbfa9e990ef0e543b0ac73f41b9585d295c
BLAKE2b-256 checksum
How to use checksums
21ac9cdea5bcfbd8511fd7062517c14cf3de8217481f4bf9bdb83464fa7e938f
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/6.1.0 CPython/3.13.7

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Sep 18, 2025.

Transparency log

Release history Release notifications | RSS feed

This release

0.0.8 This release

2 release files

0.0.7

2 release files

0.0.6

2 release files

0.0.5

2 release files

0.0.2

2 release files

0.0.1

2 release files

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page