|
| 1 | +[][buf] |
| 2 | + |
1 | 3 | # protovalidate-python |
2 | 4 |
|
3 | 5 | [](https://github.com/bufbuild/protovalidate-python/actions/workflows/ci.yaml) |
4 | 6 | [](https://github.com/bufbuild/protovalidate-python/actions/workflows/conformance.yaml) |
5 | 7 | [](https://badge.fury.io/py/protovalidate) |
6 | 8 |
|
7 | | -`protovalidate-python` is the Python implementation of [`protovalidate`](https://github.com/bufbuild/protovalidate), |
8 | | -designed to validate Protobuf messages at runtime based on user-defined validation constraints. Powered by Google's |
9 | | -Common Expression Language ([CEL](https://github.com/google/cel-spec)), it provides a flexible and efficient foundation |
10 | | -for defining and evaluating custom validation rules. The primary goal of `protovalidate` is to help developers ensure |
11 | | -data consistency and integrity across the network without requiring generated code. |
12 | | - |
13 | | -## The `protovalidate` project |
| 9 | +[Protovalidate][protovalidate] provides standard annotations to validate common constraints on messages and fields, as well as the ability to use [CEL][cel] to write custom constraints. It's the next generation of [protoc-gen-validate][protoc-gen-validate], the only widely used validation library for Protobuf. |
14 | 10 |
|
15 | | -Head over to the core [`protovalidate`](https://github.com/bufbuild/protovalidate/) repository for: |
| 11 | +With Protovalidate, you can annotate your Protobuf messages with both standard and custom validation rules: |
16 | 12 |
|
17 | | -- [The API definition](https://github.com/bufbuild/protovalidate/tree/main/proto/protovalidate/buf/validate/validate.proto): |
18 | | - used to describe validation constraints |
19 | | -- [Documentation](https://github.com/bufbuild/protovalidate/tree/main/docs): how to apply `protovalidate` effectively |
20 | | -- [Migration tooling](https://github.com/bufbuild/protovalidate/tree/main/docs/migrate.md): incrementally migrate |
21 | | - from `protoc-gen-validate` |
22 | | -- [Conformance testing utilities](https://github.com/bufbuild/protovalidate/tree/main/docs/conformance.md): for |
23 | | - acceptance testing of `protovalidate` implementations |
| 13 | +```protobuf |
| 14 | +syntax = "proto3"; |
24 | 15 |
|
25 | | -Other `protovalidate` runtime implementations include: |
| 16 | +package banking.v1; |
26 | 17 |
|
27 | | -- Go: [`protovalidate-go`](https://github.com/bufbuild/protovalidate-go) |
28 | | -- C++: [`protovalidate-cc`](https://github.com/bufbuild/protovalidate-cc) |
29 | | -- Java: [`protovalidate-java`](https://github.com/bufbuild/protovalidate-java) |
| 18 | +import "buf/validate/validate.proto"; |
30 | 19 |
|
31 | | -And others coming soon: |
| 20 | +message MoneyTransfer { |
| 21 | + string to_account_id = 1 [ |
| 22 | + // Standard rule: `to_account_id` must be a UUID |
| 23 | + (buf.validate.field).string.uuid = true |
| 24 | + ]; |
32 | 25 |
|
33 | | -- TypeScript: `protovalidate-ts` |
| 26 | + string from_account_id = 2 [ |
| 27 | + // Standard rule: `from_account_id` must be a UUID |
| 28 | + (buf.validate.field).string.uuid = true |
| 29 | + ]; |
34 | 30 |
|
35 | | -## Installation |
| 31 | + // Custom rule: `to_account_id` and `from_account_id` can't be the same. |
| 32 | + option (buf.validate.message).cel = { |
| 33 | + id: "to_account_id.not.from_account_id" |
| 34 | + message: "to_account_id and from_account_id should not be the same value" |
| 35 | + expression: "this.to_account_id != this.from_account_id" |
| 36 | + }; |
| 37 | +} |
| 38 | +``` |
36 | 39 |
|
37 | | -To install the package, use pip: |
| 40 | +Once you've added `protovalidate-python` to your project, validation is idiomatic Python: |
38 | 41 |
|
39 | | -```shell |
40 | | -pip install protovalidate |
| 42 | +```python |
| 43 | +try: |
| 44 | + protovalidate.validate(message) |
| 45 | +except protovalidate.ValidationError as e: |
| 46 | + # Handle failure. |
41 | 47 | ``` |
42 | 48 |
|
43 | | -Make sure you have the latest version of `protovalidate-python` by checking the |
44 | | -project's [PyPI page](https://pypi.org/project/protovalidate/). |
| 49 | +## Installation |
45 | 50 |
|
46 | | -## Usage |
| 51 | +> [!TIP] |
| 52 | +> The easiest way to get started with Protovalidate for RPC APIs are the quickstarts in Buf's documentation. There's one available for [Python and gRPC][grpc-python]. |
47 | 53 |
|
48 | | -### Implementing validation constraints |
| 54 | +To install the package, use `pip`: |
49 | 55 |
|
50 | | -Validation constraints are defined directly within `.proto` files. Documentation for adding constraints can be found in |
51 | | -the `protovalidate` project [README](https://github.com/bufbuild/protovalidate) and |
52 | | -its [comprehensive docs](https://github.com/bufbuild/protovalidate/tree/main/docs). |
| 56 | +```shell |
| 57 | +pip install protovalidate |
| 58 | +``` |
53 | 59 |
|
54 | | -```protobuf |
55 | | -syntax = "proto3"; |
| 60 | +## Documentation |
56 | 61 |
|
57 | | -package my.package; |
| 62 | +Comprehensive documentation for Protovalidate is available in [Buf's documentation library][protovalidate]. |
58 | 63 |
|
59 | | -import "google/protobuf/timestamp.proto"; |
60 | | -import "buf/validate/validate.proto"; |
| 64 | +Highlights for Python developers include: |
61 | 65 |
|
62 | | -message Transaction { |
63 | | - uint64 id = 1 [(buf.validate.field).uint64.gt = 999]; |
64 | | - google.protobuf.Timestamp purchase_date = 2; |
65 | | - google.protobuf.Timestamp delivery_date = 3; |
| 66 | +* The [developer quickstart][quickstart] |
| 67 | +* A comprehensive RPC quickstart for [Python and gRPC][grpc-python] |
| 68 | +* A [migration guide for protoc-gen-validate][migration-guide] users |
66 | 69 |
|
67 | | - string price = 4 [(buf.validate.field).cel = { |
68 | | - id: "transaction.price", |
69 | | - message: "price must be positive and include a valid currency symbol ($ or £)", |
70 | | - expression: "(this.startsWith('$') || this.startsWith('£')) && double(this.substring(1)) > 0" |
71 | | - }]; |
| 70 | +## Additional Languages and Repositories |
72 | 71 |
|
73 | | - option (buf.validate.message).cel = { |
74 | | - id: "transaction.delivery_date", |
75 | | - message: "delivery date must be after purchase date", |
76 | | - expression: "this.delivery_date > this.purchase_date" |
77 | | - }; |
78 | | -} |
79 | | -``` |
| 72 | +Protovalidate isn't just for Python! You might be interested in sibling repositories for other languages: |
80 | 73 |
|
81 | | -### Generating Code with `buf` |
82 | | - |
83 | | -When using the runtime library after installing it with `pip`, it's necessary to generate the Python code for the core `buf.protovalidate` Protobuf package. `buf` provides an efficient method for this: |
84 | | - |
85 | | -1. **Initialize a New Configuration File**: |
86 | | - ```shell |
87 | | - buf config init |
88 | | - ``` |
89 | | - This initializes the `buf.yaml` configuration file at the root of the Protobuf source files. |
90 | | - |
91 | | -2. **Module Configuration and Dependencies**: |
92 | | - ```yaml |
93 | | - # buf.yaml |
94 | | - version: v2 |
95 | | - deps: |
96 | | - - buf.build/bufbuild/protovalidate |
97 | | - ``` |
98 | | -
|
99 | | - Ensure your dependencies are up-to-date with: |
100 | | - ```shell |
101 | | - buf dep update |
102 | | - ``` |
103 | | - |
104 | | -3. **Setup Code Generation**: |
105 | | - ```yaml |
106 | | - # buf.gen.yaml |
107 | | - version: v2 |
108 | | - plugins: |
109 | | - - remote: buf.build/protocolbuffers/python |
110 | | - out: gen |
111 | | - ``` |
112 | | -
|
113 | | -4. **Generate Code**: |
114 | | - To generate the required Python code: |
115 | | - ```shell |
116 | | - buf generate --include-imports |
117 | | - ``` |
118 | | - |
119 | | -5. **Specify import paths**: |
120 | | - Ensure that the generated code is importable by setting the `PYTHONPATH` environment variable: |
121 | | - ```shell |
122 | | - export PYTHONPATH=$PYTHONPATH:gen |
123 | | - ``` |
124 | | - |
125 | | -If your goal is to generate code specifically for the `buf.protovalidate` Protobuf package, run: |
126 | | -```shell |
127 | | -buf generate buf.build/bufbuild/protovalidate |
128 | | -``` |
| 74 | +- [`protovalidate-go`][pv-go] (Go) |
| 75 | +- [`protovalidate-java`][pv-java] (Java) |
| 76 | +- [`protovalidate-cc`][pv-cc] (C++) |
| 77 | +- `protovalidate-es` (TypeScript and JavaScript, coming soon!) |
129 | 78 |
|
130 | | -> **Note:** For users familiar with `protoc`, while it's an alternative to `buf`, it is recommended to use tooling or frameworks like Bazel for direct code generation, as it provides an encapsulated environment for such tasks. |
| 79 | +Additionally, [protovalidate's core repository](https://github.com/bufbuild/protovalidate) provides: |
131 | 80 |
|
132 | | -### Example |
| 81 | +- [Protovalidate's Protobuf API][validate-proto] |
| 82 | +- [Conformance testing utilities][conformance] for acceptance testing of `protovalidate` implementations |
133 | 83 |
|
134 | | -```python |
135 | | -import protovalidate |
136 | | -from google.protobuf.timestamp_pb2 import Timestamp |
137 | | -from my.package import Transaction |
| 84 | +## Contribution |
138 | 85 |
|
139 | | -transaction = Transaction() |
140 | | -transaction.id = 1234 |
141 | | -transaction.price = "$5.67" |
142 | | -transaction.purchase_date.CopyFrom(Timestamp()) |
143 | | -transaction.delivery_date.CopyFrom(Timestamp()) |
| 86 | +We genuinely appreciate any help! If you'd like to contribute, check out these resources: |
144 | 87 |
|
145 | | -try: |
146 | | - protovalidate.validate(transaction) |
147 | | -except protovalidate.ValidationError as e: |
148 | | -# Report the violations |
149 | | -``` |
| 88 | +- [Contributing Guidelines][contributing]: Guidelines to make your contribution process straightforward and meaningful |
| 89 | +- [Conformance testing utilities](https://github.com/bufbuild/protovalidate/tree/main/docs/conformance.md): Utilities providing acceptance testing of `protovalidate` implementations |
150 | 90 |
|
151 | | -### Ecosystem |
| 91 | +## Related Sites |
152 | 92 |
|
153 | | -- [`protovalidate`](https://github.com/bufbuild/protovalidate) core repository |
154 | | -- [Buf](https://buf.build) |
155 | | -- [CEL Spec](https://github.com/google/cel-spec) |
| 93 | +- [Buf][buf]: Enterprise-grade Kafka and gRPC for the modern age |
| 94 | +- [Common Expression Language (CEL)][cel]: The open-source technology at the core of Protovalidate |
156 | 95 |
|
157 | 96 | ## Legal |
158 | 97 |
|
159 | 98 | Offered under the [Apache 2 license][license]. |
160 | 99 |
|
161 | | -[license]: LICENSE |
162 | 100 | [buf]: https://buf.build |
| 101 | +[cel]: https://cel.dev |
| 102 | + |
| 103 | +[pv-go]: https://github.com/bufbuild/protovalidate-go |
| 104 | +[pv-java]: https://github.com/bufbuild/protovalidate-java |
| 105 | +[pv-python]: https://github.com/bufbuild/protovalidate-python |
| 106 | +[pv-cc]: https://github.com/bufbuild/protovalidate-cc |
| 107 | + |
163 | 108 | [buf-mod]: https://buf.build/bufbuild/protovalidate |
164 | | -[cel-go]: https://github.com/google/cel-go |
165 | | -[cel-spec]: https://github.com/google/cel-spec |
| 109 | +[license]: LICENSE |
| 110 | +[contributing]: .github/CONTRIBUTING.md |
| 111 | + |
| 112 | +[protoc-gen-validate]: https://github.com/bufbuild/protoc-gen-validate |
| 113 | + |
| 114 | +[protovalidate]: https://buf.build/docs/protovalidate |
| 115 | +[quickstart]: https://buf.build/docs/protovalidate/quickstart/ |
| 116 | +[connect-go]: https://buf.build/docs/protovalidate/quickstart/connect-go/ |
| 117 | +[grpc-go]: https://buf.build/docs/protovalidate/quickstart/grpc-go/ |
| 118 | +[grpc-java]: https://buf.build/docs/protovalidate/quickstart/grpc-java/ |
| 119 | +[grpc-python]: https://buf.build/docs/protovalidate/quickstart/grpc-python/ |
| 120 | +[migration-guide]: https://buf.build/docs/migration-guides/migrate-from-protoc-gen-validate/ |
| 121 | +[conformance-executable]: ./internal/cmd/protovalidate-conformance-go/README.md |
| 122 | +[pkg-go]: https://pkg.go.dev/github.com/bufbuild/protovalidate-go |
| 123 | + |
| 124 | +[validate-proto]: https://buf.build/bufbuild/protovalidate/docs/main:buf.validate |
| 125 | +[conformance]: https://github.com/bufbuild/protovalidate/blob/main/docs/conformance.md |
| 126 | +[examples]: https://github.com/bufbuild/protovalidate/tree/main/examples |
| 127 | +[migrate]: https://buf.build/docs/migration-guides/migrate-from-protoc-gen-validate/ |
0 commit comments