Overview¶
Tip
The code snippets in this documentation are automatically tested and should work «as is».
Quick examples¶
dataclass_example.py
from dataclasses import dataclass
from io import BytesIO
from pure_protobuf.annotations import Field
from pure_protobuf.message import BaseMessage
from typing_extensions import Annotated
@dataclass
class SearchRequest(BaseMessage):
query: Annotated[str, Field(1)] = ""
page_number: Annotated[int, Field(2)] = 0
result_per_page: Annotated[int, Field(3)] = 0
request = SearchRequest(
query="hello",
page_number=1,
result_per_page=10,
)
buffer = bytes(request)
assert buffer == b"\x0A\x05hello\x10\x01\x18\x0A"
assert SearchRequest.read_from(BytesIO(buffer)) == request
pydantic_example.py
from io import BytesIO
from pure_protobuf.annotations import Field
from pure_protobuf.message import BaseMessage
from pydantic import BaseModel
from typing_extensions import Annotated
class SearchRequest(BaseMessage, BaseModel):
query: Annotated[str, Field(1)] = ""
page_number: Annotated[int, Field(2)] = 0
result_per_page: Annotated[int, Field(3)] = 0
request = SearchRequest(
query="hello",
page_number=1,
result_per_page=10,
)
buffer = bytes(request)
assert buffer == b"\x0A\x05hello\x10\x01\x18\x0A"
assert SearchRequest.read_from(BytesIO(buffer)) == request
Prerequisite
BaseMessage
requires a subclass to accept field values via keyword parameters in its __init__()
method. For most cases, one should use something like the built-in dataclasses
or a third-party package like pydantic
. But it is certainly possible to go a «vanilla» way:
test_vanilla.py
from io import BytesIO
from pure_protobuf.annotations import Field
from pure_protobuf.message import BaseMessage
from typing_extensions import Annotated
class Message(BaseMessage):
a: Annotated[int, Field(1)] = 0
def __init__(self, a: int) -> None:
self.a = a
assert Message.read_from(BytesIO(b"\x08\x96\x01")).a == 150