How to Mock a Service Mesh Sidecar Proxy in Python
Simulate a service mesh sidecar proxy with route registration, service discovery, and request proxying using a simple Python class.
Python code
48 linesclass SidecarProxy:
def __init__(self, name):
self.name = name
self.routes = {}
self.services = {}
self.requests_processed = 0
def register_service(self, service_name, address, port):
self.services[service_name] = f"{address}:{port}"
def add_route(self, path, service_name):
self.routes[path] = service_name
print(f"[{self.name}] Added route: {path} -> {service_name}")
def handle_request(self, path, method="GET"):
self.requests_processed += 1
print(f"[{self.name}] Received {method} request for {path}")
if path not in self.routes:
print(f"[{self.name}] 404 Not Found")
return None
service = self.services[self.routes[path]]
print(f"[{self.name}] Proxying to {service}")
return service
def get_stats(self):
return {
"proxy_name": self.name,
"requests_processed": self.requests_processed,
"routes_configured": len(self.routes),
"services_registered": len(self.services)
}
if __name__ == "__main__":
proxy = SidecarProxy("envoy-mock")
proxy.register_service("user-service", "10.0.0.1", 8080)
proxy.register_service("order-service", "10.0.0.2", 8081)
proxy.add_route("/api/users", "user-service")
proxy.add_route("/api/orders", "order-service")
proxy.handle_request("/api/users")
proxy.handle_request("/api/orders", "POST")
proxy.handle_request("/api/unknown")
print(f"\nProxy stats: {proxy.get_stats()}")
Output
[envoy-mock] Added route: /api/users -> user-service
[envoy-mock] Added route: /api/orders -> order-service
[envoy-mock] Received GET request for /api/users
[envoy-mock] Proxying to 10.0.0.1:8080
[envoy-mock] Received POST request for /api/orders
[envoy-mock] Proxying to 10.0.0.2:8081
[envoy-mock] Received GET request for /api/unknown
[envoy-mock] 404 Not Found
Proxy stats: {'proxy_name': 'envoy-mock', 'requests_processed': 3, 'routes_configured': 2, 'services_registered': 2}
How it works
The SidecarProxy class mimics the core behavior of a sidecar proxy like Envoy or Linkerd: it maintains a registry of backend services and a routing table mapping paths to those services. When a request arrives, handle_request looks up the route, resolves the target service address, and returns it as the proxy destination. The get_stats method provides an observability view of the proxy's runtime state, mirroring metrics you'd collect from a real sidecar. This pattern is ideal for testing microservices locally without spinning up heavyweight infrastructure, letting you validate routing logic and request flows in isolation.
Common mistakes
- Forgetting to register a service before adding a route, causing a KeyError when the route is hit
- Not incrementing request counters in all request paths, leading to inaccurate stats
- Hardcoding routes instead of implementing dynamic route updates for CI/CD-driven config
Variations
- Use a dataclass for service definitions to include health-check metadata and retry policies
- Implement circuit-breaker logic that drops requests when a service fails repeatedly
Real-world use cases
- Unit-testing microservice communication patterns before deploying to a real Kubernetes cluster.
- Building a lightweight local development environment that emulates service discovery without running Envoy.
- Validating egress routing rules and proxy config files in CI pipelines before production rollout.
Sponsored
More from Microservices patterns
- BFF aggregation pattern: combine multiple service responses in Python easy
- Backward Compatible Schema Evolution in Python medium
- Bulkhead Thread Pool per Service Mock in Python medium
- CQRS with Separate Read and Write Repositories in Python medium
- Cache-Aside Pattern in Python: Per-Service Mock easy
- Consumer Driven Contract Pact Mock in Python medium
Keep learning
Related tutorials and quizzes for this topic.