
Security News
MCP Steering Committee Launches Official MCP Registry in Preview
The MCP Steering Committee has launched the official MCP Registry in preview, a central hub for discovering and publishing MCP servers.
Mimicker is a Python-native HTTP mocking server inspired by WireMock, designed to simplify the process of stubbing and mocking HTTP endpoints for testing purposes. Mimicker requires no third-party libraries and is lightweight, making it ideal for integration testing, local development, and CI environments.
Mimicker can be installed directly from PyPI using pip or Poetry:
pip install mimicker
poetry add mimicker
To start Mimicker on a specific port with a simple endpoint, you can use the following code snippet:
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/hello").
body({"message": "Hello, World!"}).
status(200)
)
Mimicker can handle path parameters dynamically. Here's how you can mock an endpoint with a variable in the path:
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/hello/{name}")
.body({"message": "Hello, {name}!"})
.status(200)
)
# When the client sends a request to /hello/world, the response will be:
# {"message": "Hello, world!"}
Mimicker can handle query parameters dynamically. Here's how you can mock an endpoint with a variable in the query:
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/hello?name={name}")
.body({"message": "Hello, {name}!"})
.status(200)
)
# When the client sends a request to /hello?name=world, the response will be:
# {"message": "Hello, world!"}
When query parameters are not explicitly part of the path template, Mimicker will match all otherwise matching requests against those parameters as if using a wildcard. For instance
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/hello")
.body({"message": "Hello, world!"})
.status(200)
)
# When the client sends a request to /hello?name=bob, the request will match and the response will be:
# {"message": "Hello, world!"}
These implicitly matched query parameters are available through dynamic responses
using the "query_params"
key in kwargs
in response_func
(see below), e.g.
from mimicker.mimicker import mimicker, get
def custom_response(**kwargs):
query_params: Dict[str, List[str]] = kwargs['query_params']
return 200, {"message": f"Hello {query_params['name'][0]}!"}
mimicker(8080).routes(
get("/hello")
.response_func(custom_response)
)
# When the client sends a request to /hello?name=world, the request will match and the response will be:
# {"message": "Hello, world!"}
Note that because query parameters can be repeated with multiple values, they will always appear in a list of values.
You can also mock responses with custom headers:
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/hello")
.body("Hello with headers")
.headers([("Content-Type", "text/plain"), ("Custom-Header", "Value")])
.status(200)
)
# The response will include custom headers
Mimicker allows you to define multiple routes for different HTTP methods and paths. Here's an example with GET
and POST
routes:
from mimicker.mimicker import mimicker, get, post
mimicker(8080).routes(
get("/greet")
.body({"message": "Hello, world!"})
.status(200),
post("/submit")
.body({"result": "Submission received"})
.status(201)
)
# Now the server responds to:
# GET /greet -> {"message": "Hello, world!"}
# POST /submit -> {"result": "Submission received"}
You can also mock different HTTP status codes for the same endpoint:
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/status")
.body({"message": "Success"})
.status(200),
get("/error")
.body({"message": "Not Found"})
.status(404)
)
# GET /status -> {"message": "Success"} with status 200
# GET /error -> {"message": "Not Found"} with status 404
Mimicker supports JSON bodies, making it ideal for API testing:
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/json")
.body({"message": "Hello, JSON!"})
.status(200)
)
# The response will be: {"message": "Hello, JSON!"}
This is useful when testing how your code handles timeouts when calling a web API.
from mimicker.mimicker import mimicker, get
import requests
mimicker(8080).routes(
get("/wait").
delay(0.5).
body("the client should have timed out")
)
try:
resp = requests.get("http://localhost:8080/wait", timeout=0.2)
except requests.exceptions.ReadTimeout as error:
print(f"the API is unreachable due to request timeout: {error=}")
else:
# do things with the response
...
In addition to JSON bodies, Mimicker supports other types of content for the response body. Here's how you can return text or file content:
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/text")
.body("This is a plain text response")
.status(200)
)
# The response will be plain text: "This is a plain text response"
You can also return files from a mock endpoint:
from mimicker.mimicker import mimicker, get
mimicker(8080).routes(
get("/file")
.body(open("example.txt", "rb").read()) # Mock a file response
.status(200)
)
# The response will be the content of the "example.txt" file
response_func
Mimicker allows dynamic responses based on the request data using response_func
.
This feature enables you to build mock responses that adapt based on request parameters, headers, and body.
from mimicker.mimicker import mimicker, post
# Available for use with response_func:
# kwargs.get("payload")
# kwargs.get("headers")
# kwargs.get("params")
def custom_response(**kwargs):
request_payload = kwargs.get("payload")
return 200, {"message": f"Hello {request_payload.get('name', 'Guest')}"}
mimicker(8080).routes(
post("/greet")
.response_func(custom_response)
)
# POST /greet with body {"name": "World"} -> {"message": "Hello World"}
# POST /greet with empty body -> {"message": "Hello Guest"}
If you start Mimicker with port 0
, the system will automatically assign an available port. You can retrieve the actual port Mimicker is running on using the get_port
method:
from mimicker.mimicker import mimicker, get
server = mimicker(0).routes(
get("/hello")
.body({"message": "Hello, World!"})
.status(200)
)
actual_port = server.get_port()
print(f"Mimicker is running on port {actual_port}")
This is useful for test environments where a specific port is not required.
get(path)
: Defines a GET
endpoint.post(path)
: Defines a POST
endpoint.put(path)
: Defines a PUT
endpoint.delete(path)
: Defines a DELETE
endpoint.patch(path)
: Defines a PATCH
endpoint..delay(duration)
: Defines the delay in seconds waited before returning the response (optional, 0. by default)..body(content)
: Defines the response body
..status(code)
: Defines the response status code
..headers(headers)
: Defines response headers
..response_func(func)
: Defines a dynamic response function based on the request data.Mimicker includes built-in logging to help you observe and debug how your mocked endpoints behave.
By default, Mimicker logs at the INFO level and uses a colorized output for readability. You’ll see messages like:
[MIMICKER] [2025-05-04 14:52:10] INFO: ✓ Matched stub. Returning configured response.
and:
[MIMICKER] [2025-05-05 11:50:10,226] INFO: → GET /hello
Headers:
{
"host": "localhost:8080",
"user-agent": "python-requests/2.31.0",
"accept-encoding": "gzip, deflate",
"accept": "*/*",
"connection": "keep-alive"
}
You can control the log level using the MIMICKER_LOG_LEVEL
environment variable. Valid values include:
DEBUG
INFO
(default)WARNING
ERROR
CRITICAL
This will show detailed request information including method, path, headers, and body.
Mimicker supports Python 3.7 and above.
You are welcome to report 🐞 or issues, upvote 👍 feature requests, or 🗣️ discuss features and ideas @ slack community
I'm thankful to all the people who have contributed to this project.
Mimicker is released under the MIT License. see the LICENSE for more information.
FAQs
A lightweight HTTP mocking server for Python
We found that mimicker demonstrated a healthy version release cadence and project activity because the last version was released less than a year ago. It has 1 open source maintainer collaborating on the project.
Did you know?
Socket for GitHub automatically highlights issues in each pull request and monitors the health of all your open source dependencies. Discover the contents of your packages and block harmful activity before you install or update your dependencies.
Security News
The MCP Steering Committee has launched the official MCP Registry in preview, a central hub for discovering and publishing MCP servers.
Product
Socket’s new Pull Request Stories give security teams clear visibility into dependency risks and outcomes across scanned pull requests.
Research
/Security News
npm author Qix’s account was compromised, with malicious versions of popular packages like chalk-template, color-convert, and strip-ansi published.