gRPC in Python, the FastAPI way: models in, models out
Here is what a gRPC handler usually looks like in Python: # 1. write orders.proto # 2. python -m grpc_tools.protoc -I. --python_out=. --grpc_python_out=. orders.proto # 3. commit orders_pb2.py and orders_pb2_grpc.py, regenerate them at every change import grpc import orders_pb2 , orders_pb2_grpc class OrdersServicer ( orders_pb2_grpc . OrdersServicer ): async def Get ( self , request , context ):…
A gRPC handler in Python typically involves several steps: writing a `.proto` file, generating Python code using the `grpc_tools.protoc` tool, and then implementing the service logic. This process can lead to issues such as messages not being domain models, lack of validation, and drift in generated files. In a FastAPI context, creating endpoints is more streamlined and intuitive, but gRPC has its own set of challenges.
The tutorial introduces `fastgrpc3`, an open-source gRPC framework built on top of the Rust protobuf codec `protoruf`. Using `fastgrpc3`, developers can create gRPC services with Python models, eliminating the need to write `.proto` files manually. The framework supports Python 3.12 to 3.14 and integrates with `protoruf`, which compiles and encodes protobuf into Rust.
To start, you install `fastgrpc3` via pip, and Python 3.12 to 3.14 is required. The framework eliminates the need for `protoc`, as `protoruf` compiles the protobuf code into Rust and ships as a wheel. The core components of a service in `fastgrpc3` are a function and two models: request and response models.
The `orders.py` file demonstrates this concept. It imports necessary modules, defines Pydantic models (`GetOrder` and `Order`), and creates a gRPC service (`Orders`) with a unary method (`Get`). The request is validated using Pydantic before the function runs, and any invalid payload results in an `INVALID_ARGUMENT` status. The response is checked against the response model, and `GrpcError` converts to a real gRPC status that can be understood by any client, regardless of the programming language they use.
The service is encapsulated within a `GrpcApp`, which defines the server's address and whether to use insecure TLS. The `GrpcService` is added to the app, and reflection is enabled to allow tools like `grpcurl` to discover the service. The request and response models are defined using Pydantic, and a simple database (`DB`) simulates order storage.
To run the service, you execute `fastgrpc3 run orders:app`, and to call it from the command line, `grpcurl` is used with the appropriate parameters. The `.proto` contract is generated from the models, with field numbers managed by `fastgrpc3` to ensure compatibility over time. The contract can be exported to standard `.proto` files for teams using other languages such as Go, Java, or TypeScript. Integration with CI systems is also possible, checking for out-of-date contracts and breaking changes.
In summary, `fastgrpc3` simplifies gRPC development in Python by eliminating the need for manual `.proto` file management, enforcing validation through Pydantic, and providing a typed client for seamless integration. The framework ensures that the service's contract is consistently maintained and easily consumable by clients in various programming languages.
Written by urgent.news from Dev.to's reporting — not their text. Machine-written — may contain errors; check the original before relying on it.