protobuf-pydantic-gen


Nameprotobuf-pydantic-gen JSON
Version 0.1.8 PyPI version JSON
download
home_pageNone
SummaryA tool for converting between Pydantic models and Protobuf messages, specifically enabling the generation of Pydantic BaseModel classes from .proto files.
upload_time2025-07-16 02:22:58
maintainerNone
docs_urlNone
authorNone
requires_python>=3.9
licenseApache-2.0
keywords
VCS
bugtrack_url
requirements No requirements were recorded.
Travis-CI No Travis.
coveralls test coverage No coveralls.
            [English](README.md) | [δΈ­ζ–‡](README.zh.md)

# 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 transforms them into FastAPI routes. It automates `FastAPI` route generation based on `gRPC service` definitions, eliminating the need for additional code.

### Transport Protocols

| gRPC Type | Protocol | Description |
|-----------|----------|-------------|
| Unary | HTTP/JSON | Standard REST API calls |
| Server Streaming | Server-Sent Events (SSE) | HTTP streaming with `text/event-stream` |
| Client Streaming | WebSocket | Bidirectional WebSocket connection |
| Bidirectional Streaming | WebSocket | Bidirectional WebSocket connection |

# grpc_fastapi_client_gen

This tool automatically generates type-safe gRPC FastAPI clients from protobuf service definitions. It creates async HTTP clients that support unary calls, server streaming, and bidirectional streaming through WebSockets.

## πŸš€ Quick Links

- **[Quick Start Guide](QUICKSTART.md)** - Get running in 5 minutes
- **[Example Project](./example/)** - Full working example with server and client

## Features

- **protobuf-pydantic-gen**: 
  - Supports conversion of protobuf primitive types to Python primitive types  
  - Converts protobuf description language into pydantic `BaseModel` classes  
  - Transforms protobuf description language into `sqlmodel` ORM models  
  - Implements `to_protobuf` and `from_protobuf` methods for `BaseModel` classes to enable bidirectional conversion between pydantic models and protobuf messages  
  - Provides `pydantic BaseModel Field` parameter options for protobuf description files  

- **grpc_fastapi_gateway**:
  - Converts protobuf description language into gRPC services and transforms them into FastAPI routes  
  - Generates `FastAPI` routes based on `gRPC service` definitions without requiring extra code  

- **grpc_fastapi_client_gen**:
  - Generates type-safe async HTTP clients from protobuf service definitions
  - Supports all gRPC call types: unary, server streaming, client streaming, and bidirectional streaming
  - Uses HTTP/REST for unary calls, Server-Sent Events (SSE) for server streaming, and WebSockets for bidirectional streaming
  - Includes comprehensive error handling and connection management
  - Provides built-in authentication support (API key/Bearer token)
  - Generates test suites with integration, unit, and performance tests

## Installation

- Install the package:

```shell
pip install protobuf-pydantic-gen
```

- Install `pydantic.proto`

```shell
mkdir -p your_proto_path/protobuf_pydantic_gen && \
curl -o your_proto_path/protobuf_pydantic_gen/pydantic.proto https://raw.githubusercontent.com/begonia-org/pydantic-protobuf-gen/master/protobuf_pydantic_gen/pydantic.proto
```

# Example Usage of protobuf-pydantic-gen
```protobuf
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:**
    
```shell
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"
```

```python
#!/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](./example/) directory for a complete example of using `grpc_fastapi_gateway` with `protobuf-pydantic-gen`.

 - Compile the protobuf file into a pydantic model and output services.json

```shell
cd example/protos && make py
```

OR
```shell
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
```

## grpc_fastapi_client_gen Usage

### Quick Start

1. **Generate Client Code from Protobuf**

```shell
# Using the client generator plugin
python3 -m grpc_tools.protoc \
    --proto_path=./protos \
    --proto_path=./ \
    --client_out=./client \
    --client_opt=package_name=example \
    --client_opt=models_dir=./models \
    --client_opt=class_name=MyAPIClient \
    ./protos/helloworld.proto
```

2. **Or using Makefile (recommended)**

```shell
cd example/protos && make py_cli
```

### Generated Client Features

The generated client provides:

- **Type-safe async methods** for all gRPC service methods
- **Automatic serialization/deserialization** using Pydantic models
- **Multiple transport protocols**:
  - HTTP/JSON for unary calls
  - Server-Sent Events (SSE) for server streaming
  - WebSockets for bidirectional streaming
- **Built-in authentication** (API key/Bearer token support)
- **Connection management** and error handling

### Using the Generated Client

```python
import asyncio
from example.client.example_client import ExampleClient
from example.models.helloworld_model import HelloRequest, HelloReply

async def main():
    # Initialize client
    client = ExampleClient(
        base_url="http://localhost:8000",
        api_key="your-api-key",  # Optional
        timeout=30.0
    )
    
    # Unary call
    request = HelloRequest(name="Alice", language="en")
    response = await client.greeter_say_hello(request)
    print(f"Response: {response.message}")
    
    # Server streaming
    async for response in client.greeter_say_hello_stream_reply(request):
        print(f"Stream response: {response.message}")
        if some_condition:  # Control stream termination
            break
    
    # Bidirectional streaming
    async def input_generator():
        for name in ["Bob", "Charlie", "David"]:
            yield HelloRequest(name=name, language="en")
            await asyncio.sleep(1)  # Simulate delay
    
    async for response in client.greeter_say_hello_bidi_stream(input_generator()):
        print(f"Bidi response: {response.message}")

if __name__ == "__main__":
    asyncio.run(main())
```

### Client Configuration Options

```python
client = ExampleClient(
    base_url="https://api.example.com",  # Server base URL
    api_key="sk-...",                    # Optional API key for authentication
    timeout=60.0                         # Request timeout in seconds
)

# Custom headers for individual requests
custom_headers = {"X-Custom-Header": "value"}
response = await client.greeter_say_hello(request, headers=custom_headers)
```

### Plugin Parameters

When using `protoc-gen-client`, you can customize generation with these parameters:

| Parameter | Description | Default |
|-----------|-------------|---------|
| `package_name` | Python package name for imports,used for ${package_name}.models | Required |
| `models_dir` | Directory containing Pydantic models,eg:./models | Required |
| `class_name` | Generated client class name | `Client` |
| `services_json` | Path to services.json file | `{models_dir}/services.json` |
| `template_dir` | Custom Jinja2 template directory | Built-in templates |

Example with custom parameters:
```shell
python3 -m grpc_tools.protoc \
    --client_out=./output \
    --client_opt=package_name=myapp \
    --client_opt=models_dir=./myapp/models \
    --client_opt=class_name=MyCustomClient \
    --client_opt=services_json=./custom/services.json \
    ./protos/*.proto
```

## Contributing

1. Fork the repository
2. Create a feature branch
3. Make your changes
4. Add tests
5. Run the test suite
6. Submit a pull request

## License

This project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details. and supports transforming gRPC services into FastAPI routes. It automates `FastAPI` route generation based on `gRPC service` definitions, eliminating the need for additional code.

            

Raw data

            {
    "_id": null,
    "home_page": null,
    "name": "protobuf-pydantic-gen",
    "maintainer": null,
    "docs_url": null,
    "requires_python": ">=3.9",
    "maintainer_email": null,
    "keywords": null,
    "author": null,
    "author_email": "geebytes <vforfreedom96@gmail.com>",
    "download_url": "https://files.pythonhosted.org/packages/1d/a1/daba09d3c4d730ba6e196a2b4d478a08f6e90ca78956d66d9d97296f36b5/protobuf_pydantic_gen-0.1.8.tar.gz",
    "platform": null,
    "description": "[English](README.md) | [\u4e2d\u6587](README.zh.md)\n\n# protobuf-pydantic-gen\n\nThis 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.\n\n# grpc_fastapi_gateway\nThis tool converts Protocol Buffer description language into gRPC services and transforms them into FastAPI routes. It automates `FastAPI` route generation based on `gRPC service` definitions, eliminating the need for additional code.\n\n### Transport Protocols\n\n| gRPC Type | Protocol | Description |\n|-----------|----------|-------------|\n| Unary | HTTP/JSON | Standard REST API calls |\n| Server Streaming | Server-Sent Events (SSE) | HTTP streaming with `text/event-stream` |\n| Client Streaming | WebSocket | Bidirectional WebSocket connection |\n| Bidirectional Streaming | WebSocket | Bidirectional WebSocket connection |\n\n# grpc_fastapi_client_gen\n\nThis tool automatically generates type-safe gRPC FastAPI clients from protobuf service definitions. It creates async HTTP clients that support unary calls, server streaming, and bidirectional streaming through WebSockets.\n\n## \ud83d\ude80 Quick Links\n\n- **[Quick Start Guide](QUICKSTART.md)** - Get running in 5 minutes\n- **[Example Project](./example/)** - Full working example with server and client\n\n## Features\n\n- **protobuf-pydantic-gen**: \n  - Supports conversion of protobuf primitive types to Python primitive types  \n  - Converts protobuf description language into pydantic `BaseModel` classes  \n  - Transforms protobuf description language into `sqlmodel` ORM models  \n  - Implements `to_protobuf` and `from_protobuf` methods for `BaseModel` classes to enable bidirectional conversion between pydantic models and protobuf messages  \n  - Provides `pydantic BaseModel Field` parameter options for protobuf description files  \n\n- **grpc_fastapi_gateway**:\n  - Converts protobuf description language into gRPC services and transforms them into FastAPI routes  \n  - Generates `FastAPI` routes based on `gRPC service` definitions without requiring extra code  \n\n- **grpc_fastapi_client_gen**:\n  - Generates type-safe async HTTP clients from protobuf service definitions\n  - Supports all gRPC call types: unary, server streaming, client streaming, and bidirectional streaming\n  - Uses HTTP/REST for unary calls, Server-Sent Events (SSE) for server streaming, and WebSockets for bidirectional streaming\n  - Includes comprehensive error handling and connection management\n  - Provides built-in authentication support (API key/Bearer token)\n  - Generates test suites with integration, unit, and performance tests\n\n## Installation\n\n- Install the package:\n\n```shell\npip install protobuf-pydantic-gen\n```\n\n- Install `pydantic.proto`\n\n```shell\nmkdir -p your_proto_path/protobuf_pydantic_gen && \\\ncurl -o your_proto_path/protobuf_pydantic_gen/pydantic.proto https://raw.githubusercontent.com/begonia-org/pydantic-protobuf-gen/master/protobuf_pydantic_gen/pydantic.proto\n```\n\n# Example Usage of protobuf-pydantic-gen\n```protobuf\nsyntax = \"proto3\";\n\nimport \"google/protobuf/descriptor.proto\";\nimport \"protobuf_pydantic_gen/pydantic.proto\";\nimport \"google/protobuf/timestamp.proto\";\nimport \"google/protobuf/any.proto\";\nimport \"constant.proto\";\nimport \"example2.proto\";\npackage pydantic_example;\nmessage Nested {\n\n  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}];\n}\nmessage Example {\n    option (pydantic.database) = { \n        as_table: true\n        table_name: \"users\",\n        compound_index:{\n            indexs:[\"name\",\"age\"],\n            index_type:\"UNIQUE\",\n            name:\"uni_name_age\"\n        },\n        compound_index:{\n            indexs:[\"name\"],\n            index_type:\"PRIMARY\",\n            name:\"index_name\"\n        }\n    };\n\n  string name = 1[(pydantic.field) = {description: \"Name of the example\",alias: \"full_name\",default: \"John Doe\",max_length:128,primary_key:true}];\n  optional int32 age = 2 [(pydantic.field) = {description: \"Age of the example\",alias: \"years\",default: \"30\"}];\n  // Note: The default value is a string-formatted JSON array using single quotes\n  repeated string emails = 3 [(pydantic.field) = {description: \"Emails of the example\",default:'[\"example@example.com\",\"example2@example.com\"]'}];\n  repeated Example2 examples = 9 [(pydantic.field) = {description: \"Nested message\",sa_column_type:\"JSON\"}];\n  map<string, google.protobuf.Any> entry = 4 [(pydantic.field) = {description: \"Properties of the example\",default:\"{}\"}];\nNested nested=8[(pydantic.field) = {description: \"Nested message\",sa_column_type:\"JSON\"}];\n  google.protobuf.Timestamp created_at = 5 [(pydantic.field) = {description: \"Creation date of the example\",default: \"datetime.datetime.now()\",required: true}];\n  ExampleType type = 6 [(pydantic.field) = {description: \"Type of the example\",default: \"ExampleType.TYPE1\",sa_column_type:\"Enum[ExampleType]\"}];\n  float score = 7 [(pydantic.field) = {description: \"Score of the example\",default: \"0.0\",gt: 0.0,le: 100.0,field_type: \"Integer\"}];\n}\n```\n\n**Compile the protobuf file to generate pydantic models and SQLModel ORM models:**\n    \n```shell\npython3 -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\"\n```\n\n```python\n#!/usr/bin/env python\n# -*- encoding: utf-8 -*-\n'''\n@File    :   example.py\n@Time    :\n@Desc    :\n'''\n\nimport datetime\nfrom .constant_model import ExampleType\nfrom .example2_model import Example2\nfrom google.protobuf import message as _message, message_factory\nfrom protobuf_pydantic_gen.ext import PySQLModel, PydanticModel, model2protobuf, pool, protobuf2model\nfrom pydantic import BaseModel, ConfigDict, Field as _Field\nfrom sqlmodel import Column, Enum, Field, Integer, JSON, PrimaryKeyConstraint, SQLModel, UniqueConstraint\nfrom typing import Any, Dict, List, Optional, Type\n\nclass Nested(BaseModel):\n    model_config = ConfigDict(protected_namespaces=())\n\n    name: Optional[str] = _Field(\n        description=\"Name of the example\",\n        example=\"'ohn Doe\",\n        default=\"John Doe\",\n        alias=\"full_name\",\n        primary_key=True,\n        max_length=128)\n\n    def to_protobuf(self) -> _message.Message:\n        _proto = pool.FindMessageTypeByName(\"pydantic_example.Nested\")\n        _cls: Type[_message.Message] = message_factory.GetMessageClass(_proto)\n        return model2protobuf(self, _cls())\n\n    @classmethod\n    def from_protobuf(cls: Type[PydanticModel], src: _message.Message) -> PydanticModel:\n        return protobuf2model(cls, src)\n\nclass Example(SQLModel, table=True):\n    model_config = ConfigDict(protected_namespaces=())\n    __tablename__ = \"users\"\n    __table_args__ = (\n        UniqueConstraint(\n            \"name\", \"age\", name='uni_name_age'), PrimaryKeyConstraint(\n            \"name\", name='index_name'),)\n    name: Optional[str] = Field(\n        description=\"Name of the example\",\n        default=\"John Doe\",\n        alias=\"full_name\",\n        primary_key=True,\n        max_length=128,\n        sa_column_kwargs={\n            'comment': 'Name of the example'})\n    age: Optional[int] = Field(\n        description=\"Age of the example\",\n        default=30,\n        alias=\"years\",\n        sa_column_kwargs={\n            'comment': 'Age of the example'})\n    emails: Optional[List[str]] = Field(description=\"Emails of the example\", default=[\n                                        'example@example.com', 'example2@example.com'], sa_column_kwargs={'comment': 'Emails of the example'})\n    examples: Optional[List[Example2]] = Field(\n        description=\"Nested message\", default=None, sa_column=Column(JSON, doc=\"Nested message\"))\n    entry: Optional[Dict[str, Any]] = Field(description=\"Properties of the example\", default={\n    }, sa_column=Column(JSON, doc=\"Properties of the example\"))\n    nested: Optional[Nested] = Field(description=\"Nested message\", sa_column=Column(JSON, doc=\"Nested message\"))\n    created_at: datetime.datetime = Field(\n        description=\"Creation date of the example\",\n        default=datetime.datetime.now(),\n        sa_column_kwargs={\n            'comment': 'Creation date of the example'})\n    type: Optional[ExampleType] = Field(\n        description=\"Type of the example\",\n        default=ExampleType.TYPE1,\n        sa_column=Column(\n            Enum[ExampleType],\n            doc=\"Type of the example\"))\n    score: Optional[float] = Field(\n        description=\"Score of the example\",\n        default=0.0,\n        le=100.0,\n        sa_type=Integer,\n        sa_column_kwargs={\n            'comment': 'Score of the example'})\n\n    def to_protobuf(self) -> _message.Message:\n        _proto = pool.FindMessageTypeByName(\"pydantic_example.Example\")\n        _cls: Type[_message.Message] = message_factory.GetMessageClass(_proto)\n        return model2protobuf(self, _cls())\n\n    @classmethod\n    def from_protobuf(cls: Type[PySQLModel], src: _message.Message) -> PySQLModel:\n        return protobuf2model(cls, src)\n```\n\n### grpc_fastapi_gateway Usage Example\n\n - Reference [example](./example/) directory for a complete example of using `grpc_fastapi_gateway` with `protobuf-pydantic-gen`.\n\n - Compile the protobuf file into a pydantic model and output services.json\n\n```shell\ncd example/protos && make py\n```\n\nOR\n```shell\npython3 -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\n```\n\n## grpc_fastapi_client_gen Usage\n\n### Quick Start\n\n1. **Generate Client Code from Protobuf**\n\n```shell\n# Using the client generator plugin\npython3 -m grpc_tools.protoc \\\n    --proto_path=./protos \\\n    --proto_path=./ \\\n    --client_out=./client \\\n    --client_opt=package_name=example \\\n    --client_opt=models_dir=./models \\\n    --client_opt=class_name=MyAPIClient \\\n    ./protos/helloworld.proto\n```\n\n2. **Or using Makefile (recommended)**\n\n```shell\ncd example/protos && make py_cli\n```\n\n### Generated Client Features\n\nThe generated client provides:\n\n- **Type-safe async methods** for all gRPC service methods\n- **Automatic serialization/deserialization** using Pydantic models\n- **Multiple transport protocols**:\n  - HTTP/JSON for unary calls\n  - Server-Sent Events (SSE) for server streaming\n  - WebSockets for bidirectional streaming\n- **Built-in authentication** (API key/Bearer token support)\n- **Connection management** and error handling\n\n### Using the Generated Client\n\n```python\nimport asyncio\nfrom example.client.example_client import ExampleClient\nfrom example.models.helloworld_model import HelloRequest, HelloReply\n\nasync def main():\n    # Initialize client\n    client = ExampleClient(\n        base_url=\"http://localhost:8000\",\n        api_key=\"your-api-key\",  # Optional\n        timeout=30.0\n    )\n    \n    # Unary call\n    request = HelloRequest(name=\"Alice\", language=\"en\")\n    response = await client.greeter_say_hello(request)\n    print(f\"Response: {response.message}\")\n    \n    # Server streaming\n    async for response in client.greeter_say_hello_stream_reply(request):\n        print(f\"Stream response: {response.message}\")\n        if some_condition:  # Control stream termination\n            break\n    \n    # Bidirectional streaming\n    async def input_generator():\n        for name in [\"Bob\", \"Charlie\", \"David\"]:\n            yield HelloRequest(name=name, language=\"en\")\n            await asyncio.sleep(1)  # Simulate delay\n    \n    async for response in client.greeter_say_hello_bidi_stream(input_generator()):\n        print(f\"Bidi response: {response.message}\")\n\nif __name__ == \"__main__\":\n    asyncio.run(main())\n```\n\n### Client Configuration Options\n\n```python\nclient = ExampleClient(\n    base_url=\"https://api.example.com\",  # Server base URL\n    api_key=\"sk-...\",                    # Optional API key for authentication\n    timeout=60.0                         # Request timeout in seconds\n)\n\n# Custom headers for individual requests\ncustom_headers = {\"X-Custom-Header\": \"value\"}\nresponse = await client.greeter_say_hello(request, headers=custom_headers)\n```\n\n### Plugin Parameters\n\nWhen using `protoc-gen-client`, you can customize generation with these parameters:\n\n| Parameter | Description | Default |\n|-----------|-------------|---------|\n| `package_name` | Python package name for imports,used for ${package_name}.models | Required |\n| `models_dir` | Directory containing Pydantic models,eg:./models | Required |\n| `class_name` | Generated client class name | `Client` |\n| `services_json` | Path to services.json file | `{models_dir}/services.json` |\n| `template_dir` | Custom Jinja2 template directory | Built-in templates |\n\nExample with custom parameters:\n```shell\npython3 -m grpc_tools.protoc \\\n    --client_out=./output \\\n    --client_opt=package_name=myapp \\\n    --client_opt=models_dir=./myapp/models \\\n    --client_opt=class_name=MyCustomClient \\\n    --client_opt=services_json=./custom/services.json \\\n    ./protos/*.proto\n```\n\n## Contributing\n\n1. Fork the repository\n2. Create a feature branch\n3. Make your changes\n4. Add tests\n5. Run the test suite\n6. Submit a pull request\n\n## License\n\nThis project is licensed under the Apache 2.0 License - see the [LICENSE](LICENSE) file for details. and supports transforming gRPC services into FastAPI routes. It automates `FastAPI` route generation based on `gRPC service` definitions, eliminating the need for additional code.\n",
    "bugtrack_url": null,
    "license": "Apache-2.0",
    "summary": "A tool for converting between Pydantic models and Protobuf messages, specifically enabling the generation of Pydantic BaseModel classes from .proto files.",
    "version": "0.1.8",
    "project_urls": null,
    "split_keywords": [],
    "urls": [
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "5e0751aa91e89e8bcc69d208ccbd5c412ad6c662053e1abeab614c57bf142a0f",
                "md5": "e1e4c73e90e5909134eebb05c9c4cea4",
                "sha256": "56aec68388e674d2bdcf36a68b24bc2245df2cccf3f6b34ffe0f187fae4876c3"
            },
            "downloads": -1,
            "filename": "protobuf_pydantic_gen-0.1.8-py3-none-any.whl",
            "has_sig": false,
            "md5_digest": "e1e4c73e90e5909134eebb05c9c4cea4",
            "packagetype": "bdist_wheel",
            "python_version": "py3",
            "requires_python": ">=3.9",
            "size": 80939,
            "upload_time": "2025-07-16T02:22:56",
            "upload_time_iso_8601": "2025-07-16T02:22:56.474367Z",
            "url": "https://files.pythonhosted.org/packages/5e/07/51aa91e89e8bcc69d208ccbd5c412ad6c662053e1abeab614c57bf142a0f/protobuf_pydantic_gen-0.1.8-py3-none-any.whl",
            "yanked": false,
            "yanked_reason": null
        },
        {
            "comment_text": null,
            "digests": {
                "blake2b_256": "1da1daba09d3c4d730ba6e196a2b4d478a08f6e90ca78956d66d9d97296f36b5",
                "md5": "29debc497486877d0f8e11b3640ff043",
                "sha256": "9fd248cf1c56d63a5d210a6805c60b523591d346fe81add3dd656e658f5a64f8"
            },
            "downloads": -1,
            "filename": "protobuf_pydantic_gen-0.1.8.tar.gz",
            "has_sig": false,
            "md5_digest": "29debc497486877d0f8e11b3640ff043",
            "packagetype": "sdist",
            "python_version": "source",
            "requires_python": ">=3.9",
            "size": 70974,
            "upload_time": "2025-07-16T02:22:58",
            "upload_time_iso_8601": "2025-07-16T02:22:58.279575Z",
            "url": "https://files.pythonhosted.org/packages/1d/a1/daba09d3c4d730ba6e196a2b4d478a08f6e90ca78956d66d9d97296f36b5/protobuf_pydantic_gen-0.1.8.tar.gz",
            "yanked": false,
            "yanked_reason": null
        }
    ],
    "upload_time": "2025-07-16 02:22:58",
    "github": false,
    "gitlab": false,
    "bitbucket": false,
    "codeberg": false,
    "lcname": "protobuf-pydantic-gen"
}
        
Elapsed time: 2.91497s