Betterproto 2

0.9.1 · active · verified Wed Apr 15

Betterproto2 is a fork of the original betterproto library, providing an improved experience for Protobuf and gRPC in modern Python environments. It generates readable, idiomatic Python code leveraging features like dataclasses, async/await, and type hinting. While currently in active development with a release cadence of minor versions, its documentation is still evolving, and the project is subject to breaking changes. It supports Protobuf 3 & gRPC code generation, with built-in binary and JSON serialization.

Warnings

Install

Imports

Quickstart

This quickstart demonstrates how to define a simple Protobuf message, generate Python code using `protoc` (either directly or via `grpcio-tools`), and then use the generated classes for message creation, serialization to binary and JSON, and deserialization. It cleans up temporary files after execution.

# 1. Define your .proto file (e.g., example.proto)
# syntax = "proto3";
# package hello;
# message Greeting {
#   string message = 1;
# }

import os
import subprocess
import sys
from pathlib import Path

# Create a dummy .proto file for demonstration
proto_content = """
syntax = "proto3";
package hello;
message Greeting {
  string message = 1;
}
"""

proto_dir = Path("./temp_proto_gen")
proto_dir.mkdir(exist_ok=True)
proto_file = proto_dir / "example.proto"
proto_file.write_text(proto_content)

output_dir = Path("temp_betterproto_out")
output_dir.mkdir(exist_ok=True)

# 2. Generate Python code using protoc
try:
    # Using grpcio_tools if available, otherwise direct protoc
    if subprocess.run([sys.executable, '-m', 'grpc_tools.protoc', '--version'], capture_output=True, check=False).returncode == 0:
        print("Using grpcio_tools.protoc")
        subprocess.run(
            [
                sys.executable,
                '-m',
                'grpc_tools.protoc',
                f'-I={proto_dir}',
                f'--python_betterproto_out={output_dir}',
                str(proto_file)
            ],
            check=True
        )
    else:
        print("Using system protoc (ensure it's installed)")
        subprocess.run(
            [
                'protoc',
                f'-I={proto_dir}',
                f'--python_betterproto_out={output_dir}',
                str(proto_file)
            ],
            check=True
        )
    sys.path.insert(0, str(output_dir))
    from temp_proto_gen.example import Greeting # Adjusted import based on package and file

    # 3. Use the generated classes
    greeting_instance = Greeting(message="Hello betterproto2!")
    print(f"Created message: {greeting_instance}")

    # Serialize to bytes
    serialized_data = bytes(greeting_instance)
    print(f"Serialized: {serialized_data}")

    # Deserialize from bytes
    deserialized_instance = Greeting().parse(serialized_data)
    print(f"Deserialized: {deserialized_instance}")

    # Convert to dict and JSON
    print(f"To dict: {deserialized_instance.to_dict()}")
    print(f"To JSON: {deserialized_instance.to_json(indent=2)}")

except Exception as e:
    print(f"Error during quickstart: {e}")
    print("Ensure 'protoc' is installed or 'pip install grpcio-tools'")
finally:
    # Clean up generated files and directories
    import shutil
    if proto_dir.exists():
        shutil.rmtree(proto_dir)
    if output_dir.exists():
        shutil.rmtree(output_dir)
    if str(output_dir) in sys.path:
        sys.path.remove(str(output_dir))

view raw JSON →