Skip to main content
Change of provenance

The repository or configuration that created this release differ from a previous release. View details.

pygrpc-native

A gRPC server for Python whose HTTP/2 and gRPC work runs in Rust, outside the GIL. Your handlers stay in Python.

When a Python gRPC server runs out of CPU, the usual fixes are running more server processes or rewriting the servicers in another language. pygrpc-native instead moves the gRPC work itself (framing, flow control, deadlines and cancellation) onto a tokio runtime outside the GIL, and leaves your servicers, interceptors and generated code alone, so Python spends its time on your code. pygrpc_native.server() and pygrpc_native.aio.server() take the same arguments as grpcio's servers, so switching is usually a one-line change, and nothing changes for clients.

Underneath, each call reaches Python as an event: an id, the method, the request bytes and who sent it.

grpc client ──HTTP/2──▶ tokio threads (no GIL)
                          │ path → method id
                          ▼
                    event queue ──▶ recv_batch() in Python
                          ◀── respond(call_id, bytes) from any thread

Calls reach Python in batches, so a burst takes one trip across the GIL rather than one per call.

Install

pip install pygrpc-native

Wheels are published for Linux (x86_64, aarch64) and macOS (arm64, x86_64) and work on CPython 3.10 and later. To build from a checkout:

pip install maturin
maturin develop --release

With grpcio servicers

pygrpc_native.server() takes the same arguments as grpc.server() and serves servicers from grpcio-tools generated code (1.64 or later) unchanged:

from concurrent import futures
import pygrpc_native

server = pygrpc_native.server(futures.ThreadPoolExecutor(16))
greeter_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port("[::]:50051")
server.start()
server.wait_for_termination()

Status codes, error messages, metadata, deadlines, cancellation and ServicerContext behave as they do in grpcio.

Unary and server-streaming methods are served natively on one insecure port. The rest, such as client-streaming and bidirectional methods, server reflection, or handlers added only with add_generic_rpc_handlers, as code generated by grpcio-tools before 1.64 does, go to a grpcio server on a Unix socket behind it. They work, but they aren't any faster, and peer() in them is the socket.

Interceptors run as in grpcio, on the methods served here and on the fallback server. Of the server options, the message size limits, the keepalive settings (grpc.keepalive_time_ms, grpc.keepalive_timeout_ms and grpc.keepalive_permit_without_calls), grpc.max_concurrent_streams and the metadata size limits (grpc.max_metadata_size and grpc.absolute_max_metadata_size) work as in grpcio. Options that ask for something this server can't do raise an error: closing connections by age or idleness (grpc.max_connection_age_ms, grpc.max_connection_age_grace_ms, grpc.max_connection_idle_ms), grpc.max_allowed_incoming_connections, response compression and grpc.so_reuseport, as do maximum_concurrent_rpcs and TLS. Any other option is ignored, as grpcio ignores the many that only clients read. That covers the limits on client pings, which are accepted but not enforced, and grpc.http2.max_frame_size, which grpc-core's flow control overrides anyway. Values that aren't integers are ignored too, as in grpcio.

There are two known differences. If a unary handler calls send_initial_metadata() and then fails, the metadata goes out with the status, so the client sees it as trailing metadata. And a connection whose client doesn't answer a keepalive ping is closed after grpc.keepalive_timeout_ms, as gRPC's keepalive documentation describes, while grpcio waits for grpc.http2.ping_timeout_ms, a minute by default.

pygrpc_native.aio.server() does the same for grpc.aio.server():

import pygrpc_native.aio

server = pygrpc_native.aio.server()
greeter_pb2_grpc.add_GreeterServicer_to_server(Greeter(), server)
server.add_insecure_port("[::]:50051")
await server.start()
await server.wait_for_termination()

Handlers run on the event loop that called start(), uvloop included. abort() raises grpc.aio.AbortError, and a handler whose client cancels or whose deadline passes gets asyncio.CancelledError, as in grpc.aio. Streams can yield from an async generator or call context.write(), and handlers that aren't coroutines run in migration_thread_pool with grpcio's sync context, where abort() returns instead of raising. The fallback, the unsupported options and the known differences are the same as for the sync server.

Low-level API

NativeGrpcFront is the layer under server(). Each call reaches Python as an event that you answer by id:

import threading
from pygrpc_native import EVENT_CALL, NativeGrpcFront

front = NativeGrpcFront("0.0.0.0:50051", [("/echo.Echo/Say", False)])
front.start()

def serve():
    while (events := front.recv_batch(64)) is not None:
        for kind, call_id, method_id, payload, client_key in events:
            if kind == EVENT_CALL:
                front.respond(call_id, payload)

threading.Thread(target=serve).start()

Streaming, call details, response metadata, bearer tokens and metrics are covered in docs/low-level-api.md.

Compatibility

pygrpc-native follows semantic versioning, and the low-level API stays compatible within 0.x as well. tests/test_api.py pins the 0.1 names, signatures and event tuples of NativeGrpcFront: they won't change or go away, and new parameters only come after the existing ones, with a default. The keys metrics() returns won't be renamed or removed within 0.x either, though new ones may be added. server() and aio.server() follow grpcio's API, and any difference from grpcio's behavior is a bug unless it is listed in this README. Changes are listed in CHANGELOG.md.

Limitations

  • NativeGrpcFront serves unary and server-streaming methods only; other kinds can go through the fallback server. server() and aio.server() send them there on their own.
  • No TLS yet. NativeGrpcFront checks bearer tokens itself; server() and aio.server() run grpcio interceptors instead.
  • Like grpc-core, binding a Unix socket path replaces any socket file already there.
  • The server never sets SO_REUSEPORT, so binding a port another server is using fails, where grpcio's default lets both bind it. grpc.so_reuseport set to 0 is accepted; other integers raise an error.
  • Per connection: at most 1024 concurrent streams unless grpc.max_concurrent_streams says otherwise. A connection that hasn't finished the HTTP/2 preface after 120 s is dropped.
  • A call with more request metadata than the limit (16 KiB unless set) is refused. grpcio also refuses some calls at random between grpc.max_metadata_size and that limit; this server doesn't.

Benchmarks

With an empty handler on an Apple M4 Pro, pygrpc_native.server() answers about 1.5x the calls per second of grpc.server() from one client thread and about 5x from 32. On a 40-vCPU Linux container the low-level API answered about 12x at 32 threads. See benchmarks for the numbers and how they were measured.

Contributing

See CONTRIBUTING.md. Every commit needs a DCO sign-off (git commit -s).

License

Apache-2.0

Metadata

Release files for pygrpc-native 0.4.0

For a detailed explanation of source distributions (sdists) and built distributions (wheels), please see the package formats documentation.

Change of provenance

The repository or configuration that created these release files differ from that of a previous release.

We recommend inspecting the repository and configuration before proceeding. View details.

Source distribution (sdist)

Source distribution for pygrpc-native 0.4.0
File Size Uploaded Provenance Actions
pygrpc_native-0.4.0.tar.gz 198.9 kB With provenance Details for pygrpc_native-0.4.0.tar.gz

Built distributions (wheels)

Table of built distributions (wheels) for pygrpc-native 0.4.0
File Actions
pygrpc_native-0.4.0-cp310-abi3-manylinux_2_28_x86_64.whl CPython 3.10 abi3 Linux glibc 2.28+ x86-64 Details for pygrpc_native-0.4.0-cp310-abi3-manylinux_2_28_x86_64.whl
pygrpc_native-0.4.0-cp310-abi3-manylinux_2_28_aarch64.whl CPython 3.10 abi3 Linux glibc 2.28+ ARM64 Details for pygrpc_native-0.4.0-cp310-abi3-manylinux_2_28_aarch64.whl
pygrpc_native-0.4.0-cp310-abi3-macosx_11_0_arm64.whl CPython 3.10 abi3 macOS 11.0+ ARM64 Details for pygrpc_native-0.4.0-cp310-abi3-macosx_11_0_arm64.whl
pygrpc_native-0.4.0-cp310-abi3-macosx_10_12_x86_64.whl CPython 3.10 abi3 macOS 10.12+ x86-64 Details for pygrpc_native-0.4.0-cp310-abi3-macosx_10_12_x86_64.whl

Total release size: 4.6 MB

Release files / pygrpc_native-0.4.0.tar.gz

Change of provenance

This file belongs to a release with changed provenance: the repository or configuration that created the release files differ from that of a previous release.

We recommend inspecting the repository and configuration before proceeding. View details.

Download URL pygrpc_native-0.4.0.tar.gz
Size 198.9 kB
Tags Source
SHA-256 checksum
How to use checksums
7f155f38591af39f870081056ce6756cebe99bf192941ae9f9d4fdc35da0629a
BLAKE2b-256 checksum
How to use checksums
d446c2dcbf828e157c4340629adcc317efce59d668d26f80dd4e48cd7e721152
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Release files / pygrpc_native-0.4.0-cp310-abi3-manylinux_2_28_x86_64.whl

Change of provenance

This file belongs to a release with changed provenance: the repository or configuration that created the release files differ from that of a previous release.

We recommend inspecting the repository and configuration before proceeding. View details.

Download URL pygrpc_native-0.4.0-cp310-abi3-manylinux_2_28_x86_64.whl
Size 1.1 MB
Tags CPython 3.10 Linux glibc 2.28+ x86-64 abi3
SHA-256 checksum
How to use checksums
b762fdb6467ff0c425b4d1729a6d54468081122385ec851f817a0ea413baae47
BLAKE2b-256 checksum
How to use checksums
1d67618dbb78c7b880d5103dbcb778bfabb2d425d1fdc008b7e549a2fa014f52
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Release files / pygrpc_native-0.4.0-cp310-abi3-manylinux_2_28_aarch64.whl

Change of provenance

This file belongs to a release with changed provenance: the repository or configuration that created the release files differ from that of a previous release.

We recommend inspecting the repository and configuration before proceeding. View details.

Download URL pygrpc_native-0.4.0-cp310-abi3-manylinux_2_28_aarch64.whl
Size 1.1 MB
Tags CPython 3.10 Linux glibc 2.28+ ARM64 abi3
SHA-256 checksum
How to use checksums
e4bd89d9d11357d70e9d3f66c20b2cba0a991681a47cdcd8319f7a17d5d85a8e
BLAKE2b-256 checksum
How to use checksums
51b9b4b07c61adf543465e706fe92fa05b7f815d6d610e63617cd22fd3d17cf6
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Release files / pygrpc_native-0.4.0-cp310-abi3-macosx_11_0_arm64.whl

Change of provenance

This file belongs to a release with changed provenance: the repository or configuration that created the release files differ from that of a previous release.

We recommend inspecting the repository and configuration before proceeding. View details.

Download URL pygrpc_native-0.4.0-cp310-abi3-macosx_11_0_arm64.whl
Size 1.0 MB
Tags CPython 3.10 abi3 macOS 11.0+ ARM64
SHA-256 checksum
How to use checksums
45ab58310281f17e6886adae1d4fc6e371f4981957590420113d56ed5a93d42a
BLAKE2b-256 checksum
How to use checksums
c7dc729b92602bc6080f3416a23bc23c9b87d4d224faa8a71689f374d263db1e
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Release files / pygrpc_native-0.4.0-cp310-abi3-macosx_10_12_x86_64.whl

Change of provenance

This file belongs to a release with changed provenance: the repository or configuration that created the release files differ from that of a previous release.

We recommend inspecting the repository and configuration before proceeding. View details.

Download URL pygrpc_native-0.4.0-cp310-abi3-macosx_10_12_x86_64.whl
Size 1.1 MB
Tags CPython 3.10 abi3 macOS 10.12+ x86-64
SHA-256 checksum
How to use checksums
64fa8eb1f8de0ee56aa9cff2596bc4928288c68c06f8d9fa35ece57145c47a56
BLAKE2b-256 checksum
How to use checksums
216a5874433087efd7cf1240b44d52699af8193c45edbcf5a1ddb8efdcd94c42
Upload date
Uploaded using Trusted Publishing?
What is trusted publishing?
Yes
Uploaded via twine/7.0.0 CPython/3.13.16

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

Security for pygrpc-native 0.4.0

Provenance

Provenance describes where a file came from. On PyPI, provenance is shared via attestations, which provide a verifiable record of the build or publishing details. View details, limitations and caveats.

Change of provenance

The repository and configuration that created this release differ from a previous release.

While this could reflect a routine change by the project maintainers, it may also indicate that the release files have been compromised.

Select from 5 files

Attestation for pygrpc_native-0.4.0.tar.gz

PyPI Publish Attestation

PyPI verified that this artifact, at this checksum, originated from the publisher listed below.

Signed by GitHub Actions, verified by PyPI on Oct 27, 2026.

Transparency log

A note on package security

PyPI is a repository for distributing packages, not a service for auditing them. While third-party security researchers and our staff do their best to detect and remove malicious packages, PyPI cannot guarantee the quality, security or suitability of any given package.

To learn more about protecting yourself from malicious actors, visit our package security documentation.

Anthropic, PBC Visionary sponsor Bloomberg Visionary sponsor Hudson River Trading Visionary sponsor Meta Visionary sponsor NVIDIA Visionary sponsor Microsoft Sustainability sponsor Depot Continuous Integration AWS Cloud computing and Security Sponsor Datadog Monitoring Fastly CDN Google Download Analytics Sentry Error logging StatusPage Status page