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.1.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.1.0-py3-none-any.whl (8.6 kB view details)

Uploaded Python 3

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

Hashes for qx_grpc-1.1.0.tar.gz
Algorithm Hash digest
SHA256 aa3e1a6ce0f4cc506f85d0b638c65cb9fbf672310175379bd4953d57f5578ae0
MD5 c536c2ece8334bc96f91125bce696f62
BLAKE2b-256 0358573711fa07da849dc476864bfed35706e5e5dc60fd706effd997df86f4b1

See more details on using hashes here.

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

Hashes for qx_grpc-1.1.0-py3-none-any.whl
Algorithm Hash digest
SHA256 e4c925ae0660e697abce56c2e7fb15b0719bad7507e3b6dfdd629f228a1b9259
MD5 d36528acc25679086a4f7bfc0bfba45f
BLAKE2b-256 3133d3696a533f294e965fc6cd19fd648e13e1bd995d500f21f0d1233c4ab0eb

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