A tool for converting between Pydantic models and Protobuf messages, specifically enabling the generation of Pydantic BaseModel classes from .proto files.
Project description
protobuf-pydantic-gen
This tool converts Protocol Buffer description language into pydantic BaseModel classes and supports converting pydantic models back to protobuf messages. It also enables the transformation of protobuf description language into sqlmodel ORM models.
grpc_fastapi_gateway
This tool converts Protocol Buffer description language into gRPC services and supports transforming gRPC services into FastAPI routes. It automates FastAPI route generation based on gRPC service definitions, eliminating the need for additional code.
Features
- Supports conversion of protobuf primitive types to Python primitive types
- Converts protobuf description language into pydantic
BaseModelclasses - Transforms protobuf description language into
sqlmodelORM models - Implements
to_protobufandfrom_protobufmethods forBaseModelclasses to enable bidirectional conversion between pydantic models and protobuf messages - Provides
pydantic BaseModel Fieldparameter options for protobuf description files - Converts protobuf description language into gRPC services and transforms them into FastAPI routes
- Generates
FastAPIroutes based ongRPC servicedefinitions without requiring extra code
Installation
pip install protobuf-pydantic-gen
Example Usage of protobuf-pydantic-gen
syntax = "proto3";
import "google/protobuf/descriptor.proto";
import "protobuf_pydantic_gen/pydantic.proto";
import "google/protobuf/timestamp.proto";
import "google/protobuf/any.proto";
import "constant.proto";
import "example2.proto";
package pydantic_example;
message Nested {
string name = 1[(pydantic.field) = {description: "Name of the example",example: "'ohn Doe",alias: "full_name",default: "John Doe",max_length:128,primary_key:true}];
}
message Example {
option (pydantic.database) = {
as_table: true
table_name: "users",
compound_index:{
indexs:["name","age"],
index_type:"UNIQUE",
name:"uni_name_age"
},
compound_index:{
indexs:["name"],
index_type:"PRIMARY",
name:"index_name"
}
};
string name = 1[(pydantic.field) = {description: "Name of the example",alias: "full_name",default: "John Doe",max_length:128,primary_key:true}];
optional int32 age = 2 [(pydantic.field) = {description: "Age of the example",alias: "years",default: "30"}];
// Note: The default value is a string-formatted JSON array using single quotes
repeated string emails = 3 [(pydantic.field) = {description: "Emails of the example",default:'["example@example.com","example2@example.com"]'}];
repeated Example2 examples = 9 [(pydantic.field) = {description: "Nested message",sa_column_type:"JSON"}];
map<string, google.protobuf.Any> entry = 4 [(pydantic.field) = {description: "Properties of the example",default:"{}"}];
Nested nested=8[(pydantic.field) = {description: "Nested message",sa_column_type:"JSON"}];
google.protobuf.Timestamp created_at = 5 [(pydantic.field) = {description: "Creation date of the example",default: "datetime.datetime.now()",required: true}];
ExampleType type = 6 [(pydantic.field) = {description: "Type of the example",default: "ExampleType.TYPE1",sa_column_type:"Enum[ExampleType]"}];
float score = 7 [(pydantic.field) = {description: "Score of the example",default: "0.0",gt: 0.0,le: 100.0,field_type: "Integer"}];
}
Compile the protobuf file to generate pydantic models and SQLModel ORM models:
python3 -m grpc_tools.protoc --proto_path=./protos -I=./protos -I=./ --python_out=./pb --pyi_out=./pb --grpc_python_out=./pb --pydantic_out=./models "./protos/example.proto"
#!/usr/bin/env python
# -*- encoding: utf-8 -*-
'''
@File : example.py
@Time :
@Desc :
'''
import datetime
from .constant_model import ExampleType
from .example2_model import Example2
from google.protobuf import message as _message, message_factory
from protobuf_pydantic_gen.ext import PySQLModel, PydanticModel, model2protobuf, pool, protobuf2model
from pydantic import BaseModel, ConfigDict, Field as _Field
from sqlmodel import Column, Enum, Field, Integer, JSON, PrimaryKeyConstraint, SQLModel, UniqueConstraint
from typing import Any, Dict, List, Optional, Type
class Nested(BaseModel):
model_config = ConfigDict(protected_namespaces=())
name: Optional[str] = _Field(
description="Name of the example",
example="'ohn Doe",
default="John Doe",
alias="full_name",
primary_key=True,
max_length=128)
def to_protobuf(self) -> _message.Message:
_proto = pool.FindMessageTypeByName("pydantic_example.Nested")
_cls: Type[_message.Message] = message_factory.GetMessageClass(_proto)
return model2protobuf(self, _cls())
@classmethod
def from_protobuf(cls: Type[PydanticModel], src: _message.Message) -> PydanticModel:
return protobuf2model(cls, src)
class Example(SQLModel, table=True):
model_config = ConfigDict(protected_namespaces=())
__tablename__ = "users"
__table_args__ = (
UniqueConstraint(
"name", "age", name='uni_name_age'), PrimaryKeyConstraint(
"name", name='index_name'),)
name: Optional[str] = Field(
description="Name of the example",
default="John Doe",
alias="full_name",
primary_key=True,
max_length=128,
sa_column_kwargs={
'comment': 'Name of the example'})
age: Optional[int] = Field(
description="Age of the example",
default=30,
alias="years",
sa_column_kwargs={
'comment': 'Age of the example'})
emails: Optional[List[str]] = Field(description="Emails of the example", default=[
'example@example.com', 'example2@example.com'], sa_column_kwargs={'comment': 'Emails of the example'})
examples: Optional[List[Example2]] = Field(
description="Nested message", default=None, sa_column=Column(JSON, doc="Nested message"))
entry: Optional[Dict[str, Any]] = Field(description="Properties of the example", default={
}, sa_column=Column(JSON, doc="Properties of the example"))
nested: Optional[Nested] = Field(description="Nested message", sa_column=Column(JSON, doc="Nested message"))
created_at: datetime.datetime = Field(
description="Creation date of the example",
default=datetime.datetime.now(),
sa_column_kwargs={
'comment': 'Creation date of the example'})
type: Optional[ExampleType] = Field(
description="Type of the example",
default=ExampleType.TYPE1,
sa_column=Column(
Enum[ExampleType],
doc="Type of the example"))
score: Optional[float] = Field(
description="Score of the example",
default=0.0,
le=100.0,
sa_type=Integer,
sa_column_kwargs={
'comment': 'Score of the example'})
def to_protobuf(self) -> _message.Message:
_proto = pool.FindMessageTypeByName("pydantic_example.Example")
_cls: Type[_message.Message] = message_factory.GetMessageClass(_proto)
return model2protobuf(self, _cls())
@classmethod
def from_protobuf(cls: Type[PySQLModel], src: _message.Message) -> PySQLModel:
return protobuf2model(cls, src)
grpc_fastapi_gateway Usage Example
-
Reference example directory for a complete example of using
grpc_fastapi_gatewaywithprotobuf-pydantic-gen. -
Compile the protobuf file into a pydantic model and output services.json
cd example/protos && make py
OR
python3 -m grpc_tools.protoc --plugin=protoc-gen-custom=protobuf_pydantic_gen/main.py --custom_out=./example/models --python_out=./example/pb --grpc_python_out=./example/pb -I ./example -I ./example/protos helloworld.proto
Project details
Release history Release notifications | RSS feed
Download files
Download the file for your platform. If you're not sure which to choose, learn more about installing packages.
Source Distribution
Built Distribution
Filter files by name, interpreter, ABI, and platform.
If you're not sure about the file name format, learn more about wheel file names.
Copy a direct link to the current filters
File details
Details for the file protobuf_pydantic_gen-0.1.7.tar.gz.
File metadata
- Download URL: protobuf_pydantic_gen-0.1.7.tar.gz
- Upload date:
- Size: 35.1 kB
- Tags: Source
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ef3a10b7f83b0d6b3ba9c486c5503d1dcbb801a2dcff0f95116811e83b01e412
|
|
| MD5 |
2ff249202f932d25daf6c13f6f7548d5
|
|
| BLAKE2b-256 |
7820553908ebd406981b288ea19c5b76b103530b5871857ab7a4662c3e5de98a
|
File details
Details for the file protobuf_pydantic_gen-0.1.7-py3-none-any.whl.
File metadata
- Download URL: protobuf_pydantic_gen-0.1.7-py3-none-any.whl
- Upload date:
- Size: 37.9 kB
- Tags: Python 3
- Uploaded using Trusted Publishing? No
- Uploaded via: uv/0.7.2
File hashes
| Algorithm | Hash digest | |
|---|---|---|
| SHA256 |
ede6537a033d2bd914fd068c6196596034c1e9c013e9bd3e400196e5d3db662e
|
|
| MD5 |
5c493efe2608184ea839e8001e925bf1
|
|
| BLAKE2b-256 |
d6893a8d968b77d52aad9b16caaf6aab6c19519d4104ad87278291603601ed97
|