METADATA 11 KB

123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261
  1. Metadata-Version: 2.4
  2. Name: protobuf-py
  3. Version: 0.1.1
  4. Summary: Idiomatic Protocol Buffers for Python.
  5. Keywords: protobuf
  6. License-Expression: Apache-2.0
  7. License-File: LICENSE
  8. Classifier: Development Status :: 3 - Alpha
  9. Classifier: Intended Audience :: Developers
  10. Classifier: Operating System :: OS Independent
  11. Classifier: Programming Language :: Python :: 3
  12. Classifier: Programming Language :: Python :: 3 :: Only
  13. Classifier: Programming Language :: Python :: 3.10
  14. Classifier: Programming Language :: Python :: 3.11
  15. Classifier: Programming Language :: Python :: 3.12
  16. Classifier: Programming Language :: Python :: 3.13
  17. Classifier: Programming Language :: Python :: 3.14
  18. Classifier: Programming Language :: Python :: Free Threading
  19. Classifier: Topic :: File Formats
  20. Classifier: Topic :: Software Development :: Libraries :: Python Modules
  21. Classifier: Typing :: Typed
  22. Requires-Dist: protobuf-py-ext==0.1.1 ; (platform_machine == 'arm64' and platform_python_implementation == 'CPython' and sys_platform == 'darwin') or (platform_machine == 'aarch64' and platform_python_implementation == 'CPython' and sys_platform == 'linux') or (platform_machine == 'x86_64' and platform_python_implementation == 'CPython' and sys_platform == 'linux') or (platform_machine == 'AMD64' and platform_python_implementation == 'CPython' and sys_platform == 'win32') or (platform_machine == 'ARM64' and platform_python_implementation == 'CPython' and sys_platform == 'win32')
  23. Requires-Python: >=3.10
  24. Project-URL: Documentation, https://protobufpy.com/
  25. Project-URL: Homepage, https://github.com/bufbuild/protobuf-py
  26. Project-URL: Issues, https://github.com/bufbuild/protobuf-py/issues
  27. Project-URL: Source, https://github.com/bufbuild/protobuf-py
  28. Description-Content-Type: text/markdown
  29. ![The Buf logo](https://raw.githubusercontent.com/bufbuild/protobuf-py/main/.github/buf-logo.svg)
  30. # protobuf-py
  31. [![License](https://img.shields.io/badge/license-Apache--2.0-blue)](https://github.com/bufbuild/protobuf-py/blob/main/LICENSE)
  32. [![PyPI version](https://img.shields.io/pypi/v/protobuf-py)](https://pypi.org/project/protobuf-py)
  33. [![Slack](https://img.shields.io/badge/slack-buf-%23e01563)][badges_slack]
  34. `protobuf-py` is a from-scratch Protobuf library for Python 3.10+.
  35. 100% Protobuf conformance with full support for proto2, proto3, and editions. Generated code is readable, typed, and works out of the box with no dependencies or extra tooling required. Native Rust module for high-performance encoding/decoding.
  36. ```python
  37. import copy
  38. from gen.example_pb import User
  39. user = User(
  40. first_name="Alice",
  41. last_name="Smith",
  42. active=True,
  43. locations=["NYC", "LDN"],
  44. projects={"atlas": "infra"},
  45. )
  46. wire = user.to_binary()
  47. round_trip = User.from_binary(wire)
  48. print(round_trip.to_json())
  49. print(round_trip.has_field("first_name"))
  50. updated = copy.replace(round_trip, active=False) # Python 3.13+
  51. ```
  52. ## How it compares
  53. [`google-protobuf`](https://github.com/protocolbuffers/protobuf) implements the full protobuf surface, but its Python API still carries Python-2-era patterns like `SerializeToString()`, `HasField("x")`, and `WhichOneof("group")`. Generated modules use opaque descriptor blobs and absolute imports, and that import behavior causes enough packaging pain that [`fix-protobuf-imports`](https://pypi.org/project/fix-protobuf-imports/) exists just to patch generated output.
  54. [`betterproto`](https://github.com/danielgtaylor/python-betterproto) improved ergonomics, but it remains proto3-only and does not cover core protobuf features like proto2, editions, and extensions. The original project now points to `betterproto2`, and that project still calls out active development, incomplete docs, and breaking changes.
  55. [`protobuf-py`](https://pypi.org/project/protobuf-py/) is the only option that combines complete protobuf semantics with an idiomatic Python interface. You get typed generated classes, relative-import-friendly output, first-class oneof pattern matching, and modern copy semantics without extra runtime dependencies.
  56. | | `protobuf-py` | `google-protobuf` | `betterproto` |
  57. |---|---|---|---|
  58. | Spec coverage | ✅ Full (proto2, proto3, editions, extensions, custom options) | ✅ Full | ❌ Partial (proto3-only) |
  59. | Type annotations | ✅ Built-in | ❌ Third-party tooling needed | ✅ Built-in |
  60. | Conformance tests | ✅ 100% pass rate | ⚠️ Contains known failures | ❌ No conformance suite |
  61. | Readable generated code | ✅ | ❌ Classes are built only at runtime and cannot be inspected | ✅ |
  62. | Imports | ✅ Relative imports | ❌ Broken without third-party tooling | ✅ Relative imports |
  63. | Oneofs | ✅ Ergonomic, `match`-compatible | ❌ String-returning `WhichOneof()` | ⚠️ Tuple-returning helpers |
  64. | Enums | ✅ Python-native `IntEnum` | ❌ `int` + `EnumTypeWrapper` | ⚠️ Custom int subclass |
  65. | Field presence | ✅ `msg.has_field("x")` with IDE completions | ⚠️ `HasField("x")` raises for proto3 scalars | ⚠️ Helper-based |
  66. | Field assignment (`foo.x = 123`) | ✅ Direct assignment | ❌ `CopyFrom()` required | ✅ Direct assignment |
  67. | `copy.copy()` / `copy.replace()` | ✅ | ❌ | ❌ |
  68. | Global mutable registry | ✅ Explicit `Registry` | ❌ Process-wide singleton behavior | ✅ N/A |
  69. | Zero dependencies | ✅ | ✅ | ❌ Includes `grpclib`, `python-dateutil`, `typing-extensions` |
  70. ## Quickstart
  71. ```proto
  72. // proto/user.proto
  73. syntax = "proto3";
  74. message User {
  75. string first_name = 1;
  76. string last_name = 2;
  77. bool active = 3;
  78. }
  79. ```
  80. ```yaml
  81. # buf.gen.yaml
  82. version: v2
  83. inputs:
  84. - directory: proto
  85. plugins:
  86. - local: protoc-gen-py
  87. out: src/gen
  88. ```
  89. ```shellsession
  90. $ uv add protobuf-py
  91. $ uv add --dev protoc-gen-py buf-bin
  92. $ uv run -- buf generate
  93. ```
  94. You now have a typed `src/gen/user_pb.py` you can import directly.
  95. ## Generated code you can read
  96. `protoc-gen-py` - `protobuf-py`'s code generation plugin, - emits regular typed Python classes. See [Getting started](https://protobufpy.com/getting-started/installation/) and [Writing plugins](https://protobufpy.com/writing-plugins/) for setup and configuration details.
  97. ```python
  98. _UserFields: TypeAlias = Literal["first_name", "last_name", "active", "manager", "locations", "projects"]
  99. class User(Message[_UserFields]):
  100. __slots__ = ("first_name", "last_name", "active", "manager", "locations", "projects")
  101. if TYPE_CHECKING:
  102. def __init__(
  103. self,
  104. *,
  105. first_name: str = "",
  106. last_name: str = "",
  107. active: bool = False,
  108. manager: User | None = None,
  109. locations: list[str] | None = None,
  110. projects: dict[str, str] | None = None,
  111. ) -> None: ...
  112. first_name: str
  113. last_name: str
  114. active: bool
  115. manager: User | None
  116. locations: list[str]
  117. projects: dict[str, str]
  118. ```
  119. ## Feature highlights
  120. **Typed oneofs with pattern matching**
  121. ```python
  122. from protobuf import Oneof
  123. match msg.result:
  124. case Oneof(field="value", value=v):
  125. handle_value(v)
  126. case Oneof(field="error", value=e):
  127. handle_error(e)
  128. ```
  129. **Well-known types with Python-friendly helpers**
  130. ```python
  131. from datetime import UTC, datetime, timedelta
  132. from protobuf.wkt import Any, Duration, Timestamp
  133. ts = Timestamp.from_datetime(datetime.now(UTC))
  134. td = Duration.from_timedelta(timedelta(minutes=5))
  135. packed = Any.pack(user)
  136. ```
  137. **Container protocol for dynamic tools and reflection**
  138. ```python
  139. for field in user:
  140. value = user[field]
  141. print(field.name, value)
  142. print(field in user) # descriptor presence
  143. del user[field]
  144. user[field] = value
  145. ```
  146. **Project structure that behaves like Python**
  147. - Generated files use relative imports.
  148. - Generated modules fit normal package layouts.
  149. - `__init__.py` files for generated package directories are created by default.
  150. ## Migration
  151. | `google-protobuf` | `protobuf-py` |
  152. |---|---|
  153. | `msg.SerializeToString()` | `msg.to_binary()` |
  154. | `MessageType.FromString(data)` | `MessageType.from_binary(data)` |
  155. | `msg.HasField("nickname")` | `msg.has_field("nickname")` |
  156. | `msg.WhichOneof("result")` + string checks | `match msg.result` with typed `Oneof` |
  157. | `msg.Extensions[ext]` | `msg[ext]` |
  158. | `msg.child.CopyFrom(other)` | `msg.child = other` |
  159. ## Documentation
  160. - [Docs site](https://protobufpy.com/)
  161. - [Getting started](https://protobufpy.com/getting-started/installation/)
  162. - [Working with messages](https://protobufpy.com/messages/)
  163. - [Serialization](https://protobufpy.com/serialization/)
  164. - [Well-known types](https://protobufpy.com/well-known-types/)
  165. - [Reflection](https://protobufpy.com/reflection/)
  166. - [Writing plugins](https://protobufpy.com/writing-plugins/)
  167. - [API reference](https://protobufpy.com/api/)
  168. - [Code example](./examples/protobuf) — A working example that uses Protobuf to manage a persistent list of users.
  169. ## Packages
  170. - [`protobuf-py`](https://pypi.org/project/protobuf-py/): The runtime library. Contains base types, generated well-known types, and serialization.
  171. - [`protoc-gen-py`](https://pypi.org/project/protoc-gen-py/): The code generator plugin. Generates Python code that depends on `protobuf-py`.
  172. - [`protobuf-py-ext`](https://pypi.org/project/protobuf-py-ext/): The optional native extension for high performance. Used transparently when installed.
  173. ### Native extension platform support
  174. We currently publish `protobuf-py-ext` wheels for
  175. - Linux: arm64 / amd64 - glibc / musl
  176. - macOS: arm64
  177. - Windows: amd64 / arm64
  178. `protobuf-py` includes a dependency on `protobuf-py-ext` for these platforms, meaning therea are no extra steps for
  179. you to use it.
  180. Optimized wheels are published for the latest 3 versions of Python on Linux and MacOS, while other supported
  181. versions use the Python [stable ABI](https://docs.python.org/3/c-api/stable.html#stable-application-binary-interface),
  182. which will also work on unreleased Python versions and still has great performance.
  183. We believe this covers almost all users, which is important because the native extension generally improves performance
  184. by an order of magnitude or two.
  185. If you happen to be using an unsupported platform, feel free to file an issue so we can consider
  186. officially supporting it. In addition, you can easily build the extension for use on any other platform. Ensure [Rust](https://rust-lang.org/tools/install/)
  187. is installed and add `protobuf-py-ext` to your dependencies
  188. ```shellsession
  189. $ uv add protobuf-py-ext
  190. ```
  191. When your project is synced on a non-supported platform, Rust will automatically be invoked to build the
  192. extension package and it will be used with no other steps.
  193. ## Compatibility
  194. Python 3.10 and later versions are supported as long as they are [maintained by CPython](https://devguide.python.org/versions/).
  195. Versioning follows [semantic versioning](https://semver.org/), with a major version increase accompanying breaking changes
  196. and other features introduced with minor version increases. Patch version increases only contain bugfixes.
  197. More details on what we consider breaking and not can be found in the [FAQ](https://protobufpy.com/faq/#what-are-the-compatibility-guarantees).
  198. ## Status: Pre-release
  199. protobuf-py is not yet stable. The API may change before 1.0.
  200. ## Legal
  201. Offered under the [Apache 2 license](./LICENSE).
  202. [badges_slack]: https://buf.build/links/slack