Modern-DI integration for gRPC (grpcio).
Full guide: gRPC integration docs
Installation
uv add modern-di-grpc # or: pip install modern-di-grpc
Usage
gRPC has no dependency-injection system of its own, so modern-di-grpc pairs an @inject decorator with inert FromDI markers. A DIInterceptor (sync) or DIAioInterceptor (async) opens one Scope.REQUEST child container per RPC and resolves the FromDI-marked parameters of @inject-decorated servicer methods. Constructing the interceptor registers the ServicerContext provider on the container automatically — there is no separate setup call.
import typing
from concurrent import futures
import grpc
from modern_di import Container, Group, Scope, providers
from modern_di_grpc import DIInterceptor, FromDI, inject
from myapp import greeter_pb2, greeter_pb2_grpc # your generated stubs
class Settings:
def __init__(self) -> None:
self.greeting = "hello"
class Greeter:
def __init__(self, settings: Settings) -> None: # auto-injected by type
self._settings = settings
def greet(self, name: str) -> str:
return f"{self._settings.greeting}, {name}"
class AppGroup(Group):
settings = providers.Factory(Settings, scope=Scope.APP, cache=True)
greeter = providers.Factory(Greeter, scope=Scope.REQUEST)
class GreeterService(greeter_pb2_grpc.GreeterServicer):
@inject
def SayHello(
self,
request: greeter_pb2.HelloRequest,
context: grpc.ServicerContext,
greeter: typing.Annotated[Greeter, FromDI(Greeter)], # resolve by type
) -> greeter_pb2.HelloReply:
return greeter_pb2.HelloReply(message=greeter.greet(request.name))
container = Container(groups=[AppGroup], validate=True)
server = grpc.server(
futures.ThreadPoolExecutor(max_workers=10),
interceptors=[DIInterceptor(container)],
)
greeter_pb2_grpc.add_GreeterServicer_to_server(GreeterService(), server)
server.add_insecure_port("[::]:50051")
server.start()
server.wait_for_termination()
For an async server, pass DIAioInterceptor(container) to grpc.aio.server(...) and write async def servicer methods; @inject adapts to sync, async, and async-generator (server-streaming) methods across all four RPC types. gRPC has no server startup/shutdown hook, so the root container's lifecycle is yours to own — create it open, pass it to the interceptor, and close_sync() (or await close_async() on grpc.aio) after the server stops.
API
| Symbol | Description |
|---|---|
DIInterceptor(container) |
grpc.ServerInterceptor for the sync thread-pool server. Opens a Scope.REQUEST child per RPC (close_sync); auto-registers grpc_context_provider |
DIAioInterceptor(container) |
grpc.aio.ServerInterceptor for the async server. Same, with close_async |
FromDI(dependency) |
Inert marker for Annotated[T, FromDI(...)] in servicer-method signatures; accepts a provider instance or a type |
inject(method) |
Decorates a servicer method to resolve its FromDI parameters from the current RPC's child container; adapts to sync / async / async-generator methods |
fetch_di_container() |
Returns the current RPC's child container (raises LookupError outside an RPC) |
grpc_context_provider |
ContextProvider exposing grpc.ServicerContext at Scope.REQUEST; auto-registered by the interceptor |
📦 PyPI
📝 License
Part of modern-python
Built on modern-di, a dependency-injection framework with IoC container and scopes.
Browse the full list of templates and libraries in
modern-python — see the org profile for the categorized index.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file modern_di_grpc-2.1.0.tar.gz.
File metadata
- Download URL: modern_di_grpc-2.1.0.tar.gz
- Upload date:
- Size: 5.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
308f1810d7135d94373f6fc0286a1d5eef6c4aa42d0c3189c4ea9da5047d555f
|
|
| MD5 |
13acb366e03c7545cae439d107728f46
|
|
| BLAKE2b-256 |
e88f65f4894c9f7d9a1872e3f84b4fbb792021f6dcbd41ead74da7f26f3e2c25
|
File details
Details for the file modern_di_grpc-2.1.0-py3-none-any.whl.
File metadata
- Download URL: modern_di_grpc-2.1.0-py3-none-any.whl
- Upload date:
- Size: 5.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? Yes
- Uploaded via:
uv/0.11.28 {"installer":{"name":"uv","version":"0.11.28","subcommand":["publish"]},"python":null,"implementation":{"name":null,"version":null},"distro":{"name":"Ubuntu","version":"24.04","id":"noble","libc":null},"system":{"name":null,"release":null},"cpu":null,"openssl_version":null,"setuptools_version":null,"rustc_version":null,"ci":true}
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
fce50177cbf55339a6fc1737093ba75ebcbe2bfc656f4bf138e26a675a82015f
|
|
| MD5 |
636c19cb9b87b2956b18265621ff92c0
|
|
| BLAKE2b-256 |
41e8f76b86008cb8076b362742ded7550a4f4a9b6a0bd613a2ef1bd9341279d9
|