How to Build a Simple gRPC-Style Data Service in Python
Create a beginner-friendly gRPC-style service with dataclasses to simulate GetUser and CreateUser RPCs.
Python code
54 linesfrom dataclasses import dataclass
from typing import Optional
@dataclass
class User:
id: int
name: str
email: str
class UserService:
"""Simple gRPC-style service contract for beginner learners."""
def get_user(self, user_id: int) -> Optional[User]:
"""Simulated gRPC GetUser RPC."""
# Mock database
users = {
1: User(1, "Alice", "alice@example.com"),
2: User(2, "Bob", "bob@example.com"),
}
return users.get(user_id)
def create_user(self, name: str, email: str) -> User:
"""Simulated gRPC CreateUser RPC."""
# In real gRPC, this would send a request to a server
return User(id=3, name=name, email=email)
# gRPC-style message classes
@dataclass
class GetUserRequest:
user_id: int
@dataclass
class UserResponse:
user: Optional[User]
if __name__ == "__main__":
service = UserService()
# Demonstrate RPC-style calls
request = GetUserRequest(user_id=1)
response = UserResponse(user=service.get_user(request.user_id))
print(f"GetUser(1) -> {response.user}")
request = GetUserRequest(user_id=99)
response = UserResponse(user=service.get_user(request.user_id))
print(f"GetUser(99) -> {response.user}")
new_user = service.create_user("Charlie", "charlie@example.com")
print(f"CreateUser -> {new_user}")
Output
GetUser(1) -> User(id=1, name='Alice', email='alice@example.com')
GetUser(99) -> None
CreateUser -> User(id=3, name='Charlie', email='charlie@example.com')
How it works
This code uses Python dataclasses to model gRPC-style request/response messages and a service class to simulate RPC calls. The UserService acts as a stand-in for a gRPC server, with methods that mirror GetUser and CreateUser RPCs. Dataclasses simplify message definitions by auto-generating __init__, __repr__, and comparison methods. The Optional type hint indicates a method may return None when a user isn't found, mimicking how gRPC handles missing entities. This pattern helps beginners understand the structure of gRPC services without needing actual gRPC server infrastructure.
Common mistakes
- Forgetting to use `Optional` for return types that can be `None`, causing type checker errors.
- Hardcoding data in the service instead of using a real database or repository pattern.
- Confusing dataclass fields with gRPC protobuf fields — this is only a simulation, not real gRPC.
Variations
- Add a proto file and use the `grpcio` package for real wire-format communication.
- Use `typing.Protocol` to define the service interface formally.
Real-world use cases
- Prototyping the API contract of a gRPC service before wiring up the actual server.
- Teaching new team members the request/response message pattern without infrastructure setup.
- Mocking gRPC endpoints in unit tests for client-side services.
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.