Skip to main content

Qx gRPC: server factory, context-propagation interceptors, Result-to-status mapping

Project description

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 — extracts request_id, correlation_id, tenant_id, and OTel trace context from incoming gRPC metadata and populates RequestContext via contextvars, matching the behaviour of RequestContextMiddleware in qx-http.
  • qx.grpc.MetricsInterceptor — records per-method request counts and durations as Prometheus metrics.
  • qx.grpc.ExceptionInterceptor — catches ErrorException (and unexpected exceptions) and converts them to the appropriate gRPC StatusCode using status_from_error.
  • qx.grpc.status_from_error — maps Qx Error subclasses to gRPC status codes (NotFoundErrorNOT_FOUND, ConflictErrorALREADY_EXISTS, ValidationErrorINVALID_ARGUMENT, etc.).
  • qx.grpc.abort_with_error — convenience helper that calls status_from_error and raises the appropriate grpc.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_error is 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.

Project details


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.0.0.tar.gz (10.3 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

qx_grpc-1.0.0-py3-none-any.whl (8.6 kB view details)

Uploaded Python 3

File details

Details for the file qx_grpc-1.0.0.tar.gz.

File metadata

  • Download URL: qx_grpc-1.0.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

Hashes for qx_grpc-1.0.0.tar.gz
Algorithm Hash digest
SHA256 57c3fa34f07a0ea143302aa6b523b0a246aff505ca18e4f74b2fae4b82b2912b
MD5 b43e53e10eba05677a0382568f3cc9da
BLAKE2b-256 12d9e6ae3ae59e3c7ac36453db369886f15369b9a2438f2ecac0220f730b453e

See more details on using hashes here.

File details

Details for the file qx_grpc-1.0.0-py3-none-any.whl.

File metadata

  • Download URL: qx_grpc-1.0.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

Hashes for qx_grpc-1.0.0-py3-none-any.whl
Algorithm Hash digest
SHA256 f895e4d6e22f67ead6f01d6b72942a38b05dd336bee2088acc25d03cd7f69381
MD5 27b2df4f388a78bd550606abc2302624
BLAKE2b-256 e8c360b4b5f3c66d60efc82ee3a4482d26f829dd0f0b1e0230aa10ced0790228

See more details on using hashes here.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page