How to Mock an API Key Header Authentication Server in Python
A minimal HTTP server that validates requests using an X-API-Key header and returns JSON responses for authenticated and unauthenticated calls.
Python code
30 linesimport json
from http.server import BaseHTTPRequestHandler, ThreadingHTTPServer
API_KEYS = {"test-user": "secret-key-123"}
class AuthHandler(BaseHTTPRequestHandler):
def do_GET(self):
auth = self.headers.get("X-API-Key")
if not auth or auth not in API_KEYS.values():
self.send_response(401)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(json.dumps({"error": "invalid or missing API key"}).encode())
return
self.send_response(200)
self.send_header("Content-Type", "application/json")
self.end_headers()
self.wfile.write(json.dumps({"message": "authenticated", "path": self.path}).encode())
def log_message(self, format, *args):
print(format % args)
if __name__ == "__main__":
server = ThreadingHTTPServer(("localhost", 8000), AuthHandler)
print("Mock API server running on port 8000")
print("Test with: curl -H 'X-API-Key: secret-key-123' http://localhost:8000/data")
try:
server.serve_forever()
except KeyboardInterrupt:
print("\nServer stopped")
Output
When running the script:
Mock API server running on port 8000
Test with: curl -H 'X-API-Key: secret-key-123' http://localhost:8000/data
On a request with a valid key:
127.0.0.1 - - [10/Oct/2023 12:00:00] "GET /data HTTP/1.1" 200 -
The curl output for a valid key:
{"message": "authenticated", "path": "/data"}
On a request with a missing or invalid key:
127.0.0.1 - - [10/Oct/2023 12:00:01] "GET /data HTTP/1.1" 401 -
The curl output for a missing/invalid key:
{"error": "invalid or missing API key"}
How it works
The BaseHTTPRequestHandler processes each HTTP request via its do_GET method, where the X-API-Key header is read from self.headers. If the key is absent or not in the allowed values, the server sends a 401 with a JSON error body. Otherwise, it sends a 200 with an authentication success message and the request path. Using ThreadingHTTPServer allows multiple clients to connect concurrently, making the mock suitable for parallel testing. The server runs indefinitely until interrupted.
Common mistakes
- Comparing the API key against a list of valid keys without using a set for efficiency when many keys are present.
- Forgetting to encode the JSON string to bytes before writing to `wfile`.
- Not setting the `Content-Type` header consistently for every response.
Variations
- Use `BaseHTTPRequestHandler` with `HTTPServer` instead of `ThreadingHTTPServer` for a simpler single-threaded mock.
- Add a request handler for `do_POST` to simulate key-based auth for POST endpoints.
Real-world use cases
- Mocking an external API during local development to test your client's authentication logic without hitting the real service.
- Setting up a quick test fixture in a CI pipeline to verify that your code sends the correct API key header.
- Teaching or demoing how header-based authentication works in a controlled, offline environment.
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.