Skip to main content

Idiomatic Protocol Buffers for Python.

Project description

The Buf logo

protobuf-py

PyPI version License Slack

protobuf-py is an ergonomic and modern Protobuf library for Python.

Well-typed, generated code you can read. High-performance encoder/decoder written in Rust. 100% conformance.
Zero dependencies or tooling required.

Getting startedExamplesNew to Protobuf?

from gen.user_pb import User

# Messages are plain Python objects: pass fields as keyword args, or set them later.
user = User(id="123", first_name="Alice")
user.last_name = "Smith"

# Serialize to the Protobuf wire format, then parse it back.
data = user.to_binary()
user = User.from_binary(data)

print(user.first_name)  # Alice
print(user.to_json())   # {"id": "123", "firstName": "Alice", "lastName": "Smith"}

Protobuf is the easiest way to build APIs. We recommend using it with Connect for Python, which generates server stubs for you:

from connectrpc.request import RequestContext

from gen.user_connect import UserService, UserServiceASGIApplication
from gen.user_pb import GetUserRequest, GetUserResponse, User

class UserHandler(UserService):
    async def get_user(self, request: GetUserRequest, ctx: RequestContext) -> GetUserResponse:
        user = User(id=request.id, first_name="Alice", last_name="Smith")
        return GetUserResponse(user=user)

# Serve it with any ASGI server, e.g. `uvicorn server:app`.
app = UserServiceASGIApplication(UserHandler())

Connect can also generate client libraries for every major language, including your frontend. Here's what the generated Python client looks like:

from gen.user_connect import UserServiceClient
from gen.user_pb import GetUserRequest

client = UserServiceClient("http://localhost:8080")
response = client.get_user(GetUserRequest(id="123"))

print(response.user.first_name)  # Alice

Quickstart

// proto/user.proto
syntax = "proto3";

service UserService {
  rpc GetUser(GetUserRequest) returns (GetUserResponse);
}

message GetUserRequest {
  string id = 1;
}

message GetUserResponse {
  User user = 1;
}

message User {
  string id = 1;
  string first_name = 2;
  string last_name = 3;
}
# buf.gen.yaml
version: v2
inputs:
  - directory: proto
plugins:
  - local: protoc-gen-py
    out: src/gen
  - local: protoc-gen-connectrpc
    out: src/gen
$ uv add protobuf-py connectrpc
$ uv add --dev protoc-gen-py protoc-gen-connectrpc buf-bin
$ uv run -- buf generate

That's all - typed messages and Connect stubs now live in src/gen.

Feature highlights

Generated code you can read

class User(Message[_UserFields]):
    __slots__ = ("id", "first_name", "last_name")

    def __init__(
        self, *,
        id: str = "",
        first_name: str = "",
        last_name: str = "",
    ) -> None:
        ...

    id: str
    first_name: str
    last_name: str

Typed oneofs with pattern matching

from protobuf import Oneof

match msg.result:
    case Oneof(field="value", value=v):
        handle_value(v)
    case Oneof(field="error", value=e):
        handle_error(e)

Well-known types with friendly helpers

from datetime import UTC, datetime, timedelta
from protobuf.wkt import Any, Duration, Timestamp

ts = Timestamp.from_datetime(datetime.now(UTC))
td = Duration.from_timedelta(timedelta(minutes=5))
packed = Any.pack(user)

Seamless reflection

# Iterate over message fields
for field in user:
    # Access field name / value
    value = user[field]
    print(field.name, value)

    # Check for presence
    print(field in user)

    # Assign / delete fields
    user[field] = value
    del user[field]

How it compares

  • google-protobuf is complete, but generates code with unreadable binary blobs, broken imports, and a hostile API.
  • betterproto improves ergonomics, but it is proto3-only. The original project now points to betterproto2, which calls out active development, incomplete docs, and breaking changes.
Click here for a full comparison.
protobuf-py google-protobuf betterproto
Spec coverage ✅ 100% ⚠️ Known conformance failures ❌ proto3-only
Type annotations ✅ Built-in ❌ Third-party tooling needed ✅ Built-in
Readable generated code ❌ Classes are built only at runtime and cannot be inspected
Imports ✅ Relative imports ❌ Broken without third-party tooling ✅ Relative imports
Oneofs ✅ Ergonomic, match-compatible ❌ String-returning WhichOneof() ⚠️ Tuple-returning helpers
Enums ✅ Python-native IntEnum int + EnumTypeWrapper ⚠️ Custom int subclass
Field presence msg.has_field("x") with IDE completions ⚠️ HasField("x") raises for proto3 scalars ⚠️ Helper-based
Field assignment (foo.x = 123) ✅ Direct assignment CopyFrom() required ✅ Direct assignment
copy.copy() / copy.replace()
Global mutable registry ✅ Explicit Registry ❌ Process-wide singleton behavior ✅ N/A
Zero dependencies ❌ Includes grpclib, python-dateutil, typing-extensions

Migration guide

google-protobuf protobuf-py
msg.SerializeToString() msg.to_binary()
MessageType.FromString(data) MessageType.from_binary(data)
msg.HasField("nickname") msg.has_field("nickname")
msg.WhichOneof("result") + string checks match msg.result with typed Oneof
msg.Extensions[ext] msg[ext]
msg.child.CopyFrom(other) msg.child = other

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

protobuf_py-0.2.0.tar.gz (148.8 kB view details)

Uploaded Source

Built Distribution

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

protobuf_py-0.2.0-py3-none-any.whl (199.9 kB view details)

Uploaded Python 3

File details

Details for the file protobuf_py-0.2.0.tar.gz.

File metadata

  • Download URL: protobuf_py-0.2.0.tar.gz
  • Upload date:
  • Size: 148.8 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for protobuf_py-0.2.0.tar.gz
Algorithm Hash digest
SHA256 e4f2e08c8c99a0d652f20c7e52d9290e04e14f4f086fc16a83ce728bd509f0ba
MD5 bffb67133c8c1b9d4a348ff3b2ec3169
BLAKE2b-256 0656b93a2ed9588779cd19dff9d62a611a7852987db195a0c9e6ca6d4a66682f

See more details on using hashes here.

Provenance

The following attestation bundles were made for protobuf_py-0.2.0.tar.gz:

Publisher: release.yaml on bufbuild/protobuf-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file protobuf_py-0.2.0-py3-none-any.whl.

File metadata

  • Download URL: protobuf_py-0.2.0-py3-none-any.whl
  • Upload date:
  • Size: 199.9 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.13

File hashes

Hashes for protobuf_py-0.2.0-py3-none-any.whl
Algorithm Hash digest
SHA256 6811340f5a803c4e23575d9ee47c00c1385e18d93964b8cbacb0fa86eb3378f3
MD5 aafbae761c9234bf702b2da216b21277
BLAKE2b-256 7478f86aba47416d66fab4f522bca7916920b94e5e5cf73e79ea49c6a5e5c8ab

See more details on using hashes here.

Provenance

The following attestation bundles were made for protobuf_py-0.2.0-py3-none-any.whl:

Publisher: release.yaml on bufbuild/protobuf-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

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