How to Build a Batch Operations Multi-Status 207 Mock Server in Python
Build a mock HTTP server that accepts a batch of operations and returns HTTP 207 Multi-Status with per-operation status codes in JSON.
Python code
41 linesfrom http.server import BaseHTTPRequestHandler, HTTPServer
import json
class BatchHandler(BaseHTTPRequestHandler):
def do_POST(self):
if self.path != "/batch":
self.send_response(404)
self.end_headers()
return
content_length = int(self.headers.get("Content-Length", 0))
body = json.loads(self.rfile.read(content_length) or b"{}")
operations = body.get("operations", [])
results = []
for op in operations:
op_id = op.get("id")
action = op.get("action")
if action == "create":
results.append({"id": op_id, "status": 201, "message": "Created"})
elif action == "update":
results.append({"id": op_id, "status": 200, "message": "Updated"})
elif action == "delete":
results.append({"id": op_id, "status": 200, "message": "Deleted"})
else:
results.append({"id": op_id, "status": 422, "message": "Invalid action"})
response_body = json.dumps({"results": results}).encode()
self.send_response(207)
self.send_header("Content-Type", "application/json")
self.send_header("Content-Length", str(len(response_body)))
self.end_headers()
self.wfile.write(response_body)
def log_message(self, format, *args):
pass
if __name__ == "__main__":
server = HTTPServer(("localhost", 8080))
print("Batch server running on http://localhost:8080")
server.serve_forever()
Output
Batch server running on http://localhost:8080
# When POSTing to /batch with operations, the response will be 207 with:
{
"results": [
{"id": "1", "status": 201, "message": "Created"},
{"id": "2", "status": 200, "message": "Updated"},
{"id": "3", "status": 422, "message": "Invalid action"}
]
}
How it works
The handler uses BaseHTTPRequestHandler to create a simple HTTP server without third-party dependencies. The do_POST method reads the request body, parses JSON, and iterates over operations, building a list of per-operation statuses. It always responds with HTTP 207 Multi-Status as defined by WebDAV, even if individual operations fail. This pattern is common in APIs that need to report partial success or failure for batch requests.
Common mistakes
- Not checking Content-Length and reading too little or too much data
- Returning 404 for unknown paths but still sending a JSON body
- Forgetting to set Content-Type header to application/json
- Not handling malformed JSON input gracefully
Variations
- Use Flask or FastAPI with a JSON request validation library instead of raw BaseHTTPRequestHandler
- Add async support with aiohttp or Tornado for higher concurrency
Real-world use cases
- Mocking an external API's batch endpoints during integration testing to simulate mixed success/failure responses.
- Building a lightweight internal tool that accepts bulk data operations and reports per-item errors for data cleanup.
- Implementing a rate-limiting or throttling proxy that forwards batch requests and aggregates statuses for clients.
Sponsored
More from API design & gRPC
- Build a Bulk Array POST Mock Server in Python medium
- Build a Mock REST API with PUT and GET in Python medium
- Convert Protobuf to JSON and Dict in Python easy
- Create a Data Helper in Python for gRPC-style APIs easy
- Format data in Python using dataclasses like gRPC messages easy
- Generate an OpenAPI Spec from Mock Routes in Python easy
Keep learning
Related tutorials and quizzes for this topic.