qx-grpc
gRPC server factory and interceptor suite for the Qx framework — RequestContext propagation, Prometheus metrics, and Result-to-gRPC-status mapping.
What lives here
qx.grpc.create_grpc_server— builds an async gRPC server with the standard Qx interceptor stack pre-installed. Accepts a list of servicer registrations and optional port configuration.qx.grpc.RequestContextInterceptor— extractsrequest_id,correlation_id,tenant_id, and OTel trace context from incoming gRPC metadata and populatesRequestContextviacontextvars, matching the behaviour ofRequestContextMiddlewareinqx-http.qx.grpc.MetricsInterceptor— records per-method request counts and durations as Prometheus metrics.qx.grpc.ExceptionInterceptor— catchesErrorException(and unexpected exceptions) and converts them to the appropriate gRPCStatusCodeusingstatus_from_error.qx.grpc.status_from_error— maps QxErrorsubclasses to gRPC status codes (NotFoundError→NOT_FOUND,ConflictError→ALREADY_EXISTS,ValidationError→INVALID_ARGUMENT, etc.).qx.grpc.abort_with_error— convenience helper that callsstatus_from_errorand raises the appropriategrpc.aio.AbortError.
Usage
from qx.grpc import create_grpc_server
import grpc
from myapp.grpc import user_pb2_grpc, UserServicer
server = create_grpc_server(
port=50051,
metrics=metrics,
servicers=[
(user_pb2_grpc.add_UserServiceServicer_to_server, UserServicer(container)),
],
)
await server.start()
await server.wait_for_termination()
Servicer using the Mediator
from qx.grpc import abort_with_error
from qx.cqrs import Mediator
class UserServicer(UserServiceServicer):
def __init__(self, container: Container) -> None:
self._mediator = container.resolve_sync(Mediator)
async def GetUser(self, request, context):
result = await self._mediator.send(GetUserQuery(user_id=UUID(request.user_id)))
if not result.is_success:
abort_with_error(context, result.error)
return UserResponse(id=str(result.value.id), email=result.value.email)
Design rules
- Interceptors mirror the HTTP middleware stack so gRPC and HTTP endpoints have identical observability and context propagation behaviour.
status_from_erroris the single mapping point between Qx errors and gRPC statuses — extend it for domain-specific status codes rather than mapping in individual servicers.- This package is a V2 scope item; the API is stable but the servicer helpers are intentionally thin. Heavy gRPC-specific logic belongs in the service layer, not the framework.
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
qx_grpc-1.1.0.tar.gz
(10.3 kB
view details)
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 qx_grpc-1.1.0.tar.gz.
File metadata
- Download URL: qx_grpc-1.1.0.tar.gz
- Upload date:
- Size: 10.3 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
aa3e1a6ce0f4cc506f85d0b638c65cb9fbf672310175379bd4953d57f5578ae0
|
|
| MD5 |
c536c2ece8334bc96f91125bce696f62
|
|
| BLAKE2b-256 |
0358573711fa07da849dc476864bfed35706e5e5dc60fd706effd997df86f4b1
|
File details
Details for the file qx_grpc-1.1.0-py3-none-any.whl.
File metadata
- Download URL: qx_grpc-1.1.0-py3-none-any.whl
- Upload date:
- Size: 8.6 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via:
twine/6.1.0 CPython/3.13.12
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
e4c925ae0660e697abce56c2e7fb15b0719bad7507e3b6dfdd629f228a1b9259
|
|
| MD5 |
d36528acc25679086a4f7bfc0bfba45f
|
|
| BLAKE2b-256 |
3133d3696a533f294e965fc6cd19fd648e13e1bd995d500f21f0d1233c4ab0eb
|