A mock server that mimics OpenAI and Anthropic API formats for testing
Project description
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:
responses: Maps input prompts to predefined responsesdefaults: Contains default configurations like the unknown response messagesettings: 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 laglag_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
- Clone the repository:
git clone https://github.com/lukehinds/mockllm.git
cd mockllm
- 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
- 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
- Set up the responses.yml:
cp example.responses.yml responses.yml
- Validate your responses file (optional):
mockllm validate responses.yml
- 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:
- 📚 Full Documentation - Complete guides and API reference
- 🚀 Quick Start Guide - Get running in 5 minutes
- 🔌 Provider Development - Create custom providers
- ⚙️ Configuration Guide - Set up response mappings
- 💡 Examples - Real-world implementations
🧪 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:
- Fork the repository
- Create a feature branch:
git checkout -b feature/amazing-feature - Make your changes
- Run tests:
make test - Run linting:
make lint - Submit a pull request
For detailed contribution guidelines, see our Contributing Guide.
💬 Community
Join our community:
- GitHub Discussions - Ask questions and share ideas
- Discord Server - Chat with the community
- Issue Tracker - Report bugs or request features
📄 License
This project is licensed under the Apache 2.0 License.
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
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file mockllm-0.0.8.tar.gz.
File metadata
- Download URL: mockllm-0.0.8.tar.gz
- Upload date:
- Size: 192.6 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
1c389da1e0a88cfd40db0e0fd3147de86875e3e47bdd96bebfeae7291e49cc28
|
|
| MD5 |
b4cce47154b58e0041a27ea5a1e94242
|
|
| BLAKE2b-256 |
c6f5891d2090f7577dd811415e3cf04bfbf84244d1a9f31601c4aae176aad394
|
Provenance
The following attestation bundles were made for mockllm-0.0.8.tar.gz:
Publisher:
publish.yml on lukehinds/mockllm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mockllm-0.0.8.tar.gz -
Subject digest:
1c389da1e0a88cfd40db0e0fd3147de86875e3e47bdd96bebfeae7291e49cc28 - Sigstore transparency entry: 533380774
- Sigstore integration time:
-
Permalink:
lukehinds/mockllm@a4d7c047bd4a76f245529d27b37ac5cacd44e784 -
Branch / Tag:
refs/tags/v0.0.8 - Owner: https://github.com/lukehinds
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a4d7c047bd4a76f245529d27b37ac5cacd44e784 -
Trigger Event:
release
-
Statement type:
File details
Details for the file mockllm-0.0.8-py3-none-any.whl.
File metadata
- Download URL: mockllm-0.0.8-py3-none-any.whl
- Upload date:
- Size: 24.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via: twine/6.1.0 CPython/3.13.7
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
2af2d455d8cdebbd99166461734c5bbfa9e990ef0e543b0ac73f41b9585d295c
|
|
| MD5 |
a4d17d67632da6c77fde36bf36c4a820
|
|
| BLAKE2b-256 |
21ac9cdea5bcfbd8511fd7062517c14cf3de8217481f4bf9bdb83464fa7e938f
|
Provenance
The following attestation bundles were made for mockllm-0.0.8-py3-none-any.whl:
Publisher:
publish.yml on lukehinds/mockllm
-
Statement:
-
Statement type:
https://in-toto.io/Statement/v1 -
Predicate type:
https://docs.pypi.org/attestations/publish/v1 -
Subject name:
mockllm-0.0.8-py3-none-any.whl -
Subject digest:
2af2d455d8cdebbd99166461734c5bbfa9e990ef0e543b0ac73f41b9585d295c - Sigstore transparency entry: 533380777
- Sigstore integration time:
-
Permalink:
lukehinds/mockllm@a4d7c047bd4a76f245529d27b37ac5cacd44e784 -
Branch / Tag:
refs/tags/v0.0.8 - Owner: https://github.com/lukehinds
-
Access:
public
-
Token Issuer:
https://token.actions.githubusercontent.com -
Runner Environment:
github-hosted -
Publication workflow:
publish.yml@a4d7c047bd4a76f245529d27b37ac5cacd44e784 -
Trigger Event:
release
-
Statement type: