llmfaker
A mock server and in-process faker for OpenAI and Anthropic APIs, built for Python testing. Monkey-patches official LLM client libraries to intercept calls without network overhead.
Features
- In-process patching of
openai,anthropic,litellm, andlangchainclients - Fluent builder API for configuring responses
- Pattern matching: exact, regex, predicate-based, and template rendering
- Streaming support with realistic SSE emission (OpenAI and Anthropic formats)
- Failure injection: rate limits, timeouts, mid-stream disconnects, malformed JSON
- Latency simulation with configurable TTFT and inter-token delays
- Record/replay cassettes for integration testing
- Multi-turn conversation scripting and tool-call sequences
- Token counting and cost estimation via pricing tables
- Pytest plugin with
llm_fakerandllm_recordingfixtures - Standalone mock server mode via CLI
Installation
pip install llmfaker
Quick Start
In-process (for unit tests)
from llmfaker import LLMFaker
import openai
client = openai.OpenAI(api_key="fake")
with LLMFaker() as faker:
faker.when(prompt_contains="weather").respond("It's sunny!")
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "What's the weather?"}],
)
print(response.choices[0].message.content) # "It's sunny!"
Pytest plugin
def test_my_feature(llm_faker):
llm_faker.when(prompt_contains="hello").respond("Hi!")
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "hello"}],
)
assert "Hi!" in response.choices[0].message.content
assert len(llm_faker.calls) == 1
Cassette record/replay
def test_real_api_behavior(llm_recording):
# First run: calls real API and records to cassette
# Subsequent runs: replays from cassette file
response = client.chat.completions.create(
model="gpt-4",
messages=[{"role": "user", "content": "hello"}],
)
assert response.choices[0].message.content
Failure injection
with LLMFaker() as faker:
with faker.fail(rate=1.0, status=429, retry_after=30):
# All calls will get a 429 rate limit error
...
Standalone mock server
mockllm start --responses responses.yml --port 8000
YAML Configuration
responses:
"what colour is the sky?": "The sky is blue due to Rayleigh scattering."
"tell me a joke": "Why don't programmers like nature? Too many bugs!"
defaults:
unknown_response: "I don't know the answer to that."
settings:
lag_enabled: true
lag_factor: 10
Development
pip install -r requirements.txt
pip install -e .
# Run tests
python -m pytest tests/ -v
License
Inspired by mockllm.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
llmfaker-0.1.0.tar.gz
(114.8 kB
view details)
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
llmfaker-0.1.0-py3-none-any.whl
(88.6 kB
view details)
File details
Details for the file llmfaker-0.1.0.tar.gz.
File metadata
- Download URL: llmfaker-0.1.0.tar.gz
- Upload date:
- Size: 114.8 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
eead8e3481eafebccf96382f0f83fc24d781f834d2cc9958c240f358605d8e5c
|
|
| MD5 |
4794c5a9a8cd3fe9aa1cd76fba68118a
|
|
| BLAKE2b-256 |
b97cd47a63be466d03bf87f14203fdb0e2bd41c508c664e63b4d610617ab7bd8
|
File details
Details for the file llmfaker-0.1.0-py3-none-any.whl.
File metadata
- Download URL: llmfaker-0.1.0-py3-none-any.whl
- Upload date:
- Size: 88.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.2.0 CPython/3.12.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
67562fbf8d0292d64891ce3785d3ab3fed1d5ba6f3307f45891e3353e578d1fd
|
|
| MD5 |
4a8691c9f75b758360be7015551c126c
|
|
| BLAKE2b-256 |
12d57a846ecd570a9dda5ff1842d0ab374c48f0466bd2da57c1ba35ae7b58a54
|