bufbuild/protovalidate-py

Protocol Buffer Validation for Python.

67

stars

392

commits

Python

primary language

Sep 7, 2026

updated

protovalidate.com
cel
common-expression-language
protobuf
protocol-buffers
python

README

The Buf logo

protovalidate-py

CI PyPI version

Protovalidate is the semantic validation library for Protobuf. It provides standard annotations to validate common rules on messages and fields, as well as the ability to use CEL to write custom rules. It's the next generation of protoc-gen-validate.

With Protovalidate, you can annotate your Protobuf messages with both standard and custom validation rules:

syntax = "proto3";

package acme.user.v1;

import "buf/validate/validate.proto";

message User {
  string id = 1 [(buf.validate.field).string.uuid = true];
  uint32 age = 2 [(buf.validate.field).uint32.lte = 150]; // We can only hope.
  string email = 3 [(buf.validate.field).string.email = true];
  string first_name = 4 [(buf.validate.field).string.max_len = 64];
  string last_name = 5 [(buf.validate.field).string.max_len = 64];

  option (buf.validate.message).cel = {
    id: "first_name_requires_last_name"
    message: "last_name must be present if first_name is present"
    expression: "!has(this.first_name) || has(this.last_name)"
  };
}

Once you've added protovalidate to your project, validation is idiomatic Python:

try:
    protovalidate.validate(message)
except protovalidate.ValidationError as e:
    # Handle failure.

Installation

[!TIP] 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.

To install the package, use pip:

pip install protovalidate

protovalidate is implemented as a Python native extension. We publish wheels for common platforms and you will usually download a pre-built wheel. For others, ensure you have Rust and a C++ compiler available, and it will be automatically built during installation.

Documentation

Comprehensive documentation for Protovalidate is available at protovalidate.com.

Highlights for Python developers include:

Additional languages and repositories

Protovalidate isn't just for Python! You might be interested in sibling repositories for other languages:

Additionally, protovalidate's core repository provides:

Benchmarks

We include a set of benchmarks to verify different types of validation operations based on pytest-benchmark. You can run them with

$ uv run poe bench

This persists the runs results. It is often helpful to compare benchmark results between runs, for example before and after an optimization. To compare persisted results, use

$ uv run poe bench-compare

Contributing

We genuinely appreciate any help! If you'd like to contribute, check out these resources:

Offered under the Apache 2 license.

Contributors

dependabot[bot]

123 commits

Alfus

71 commits

stefanvanburen

66 commits

renovate[bot]

43 commits

bufbuild/protovalidate-py

Protocol Buffer Validation for Python.

67

stars

392

commits

Python

primary language

Sep 7, 2026

updated

protovalidate.com
cel
common-expression-language
protobuf
protocol-buffers
python

README

The Buf logo

protovalidate-py

CI PyPI version

Protovalidate is the semantic validation library for Protobuf. It provides standard annotations to validate common rules on messages and fields, as well as the ability to use CEL to write custom rules. It's the next generation of protoc-gen-validate.

With Protovalidate, you can annotate your Protobuf messages with both standard and custom validation rules:

syntax = "proto3";

package acme.user.v1;

import "buf/validate/validate.proto";

message User {
  string id = 1 [(buf.validate.field).string.uuid = true];
  uint32 age = 2 [(buf.validate.field).uint32.lte = 150]; // We can only hope.
  string email = 3 [(buf.validate.field).string.email = true];
  string first_name = 4 [(buf.validate.field).string.max_len = 64];
  string last_name = 5 [(buf.validate.field).string.max_len = 64];

  option (buf.validate.message).cel = {
    id: "first_name_requires_last_name"
    message: "last_name must be present if first_name is present"
    expression: "!has(this.first_name) || has(this.last_name)"
  };
}

Once you've added protovalidate to your project, validation is idiomatic Python:

try:
    protovalidate.validate(message)
except protovalidate.ValidationError as e:
    # Handle failure.

Installation

[!TIP] 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.

To install the package, use pip:

pip install protovalidate

protovalidate is implemented as a Python native extension. We publish wheels for common platforms and you will usually download a pre-built wheel. For others, ensure you have Rust and a C++ compiler available, and it will be automatically built during installation.

Documentation

Comprehensive documentation for Protovalidate is available at protovalidate.com.

Highlights for Python developers include:

Additional languages and repositories

Protovalidate isn't just for Python! You might be interested in sibling repositories for other languages:

Additionally, protovalidate's core repository provides:

Benchmarks

We include a set of benchmarks to verify different types of validation operations based on pytest-benchmark. You can run them with

$ uv run poe bench

This persists the runs results. It is often helpful to compare benchmark results between runs, for example before and after an optimization. To compare persisted results, use

$ uv run poe bench-compare

Contributing

We genuinely appreciate any help! If you'd like to contribute, check out these resources:

Offered under the Apache 2 license.

Contributors

dependabot[bot]

123 commits

Alfus

71 commits

stefanvanburen

66 commits

renovate[bot]

43 commits

Languages

Python

57.6%

Rust

34.4%

C++

5.9%

C

2.1%