blob: c27120e4398d3cf9fa4bfe0cc10fe7ecac6f31b1 [file] [view]
---
title: Python
sidebar_position: 3
id: python
license: |
Licensed to the Apache Software Foundation (ASF) under one or more
contributor license agreements. See the NOTICE file distributed with
this work for additional information regarding copyright ownership.
The ASF licenses this file to You under the Apache License, Version 2.0
(the "License"); you may not use this file except in compliance with
the License. You may obtain a copy of the License at
http://www.apache.org/licenses/LICENSE-2.0
Unless required by applicable law or agreed to in writing, software
distributed under the License is distributed on an "AS IS" BASIS,
WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
See the License for the specific language governing permissions and
limitations under the License.
---
## Output Layout
Python output is one module per schema file, for example:
- `<python_out>/addressbook.py`
## Type Generation
Unions generate a case enum plus a `Union` subclass with typed helpers:
```python
class AnimalCase(Enum):
DOG = 1
CAT = 2
class Animal(Union):
@classmethod
def dog(cls, v: Dog) -> "Animal": ...
def case(self) -> AnimalCase: ...
def case_id(self) -> int: ...
def is_dog(self) -> bool: ...
def dog_value(self) -> Dog: ...
def set_dog(self, v: Dog) -> None: ...
```
Messages generate `@pyfory.dataclass` types, and nested types stay nested:
```python
@pyfory.dataclass
class Person:
class PhoneType(IntEnum):
MOBILE = 0
HOME = 1
WORK = 2
@pyfory.dataclass
class PhoneNumber:
number: str = pyfory.field(id=1, default="")
phone_type: Person.PhoneType = pyfory.field(id=2, default=None)
name: str = pyfory.field(id=1, default="")
phones: List[Person.PhoneNumber] = pyfory.field(id=7, default_factory=list)
pet: Animal = pyfory.field(id=8, default=None)
def to_bytes(self) -> bytes: ...
@classmethod
def from_bytes(cls, data: bytes) -> "Person": ...
```
## Registration
Generated registration function:
```python
def register_addressbook_types(fory: pyfory.Fory):
fory.register_union(Animal, type_id=106, serializer=AnimalSerializer(fory))
fory.register_type(Person, type_id=100)
fory.register_type(Person.PhoneType, type_id=101)
fory.register_type(Person.PhoneNumber, type_id=102)
fory.register_type(Dog, type_id=104)
fory.register_type(Cat, type_id=105)
fory.register_type(AddressBook, type_id=103)
```
For schemas without explicit `[id=...]`, generated registration uses computed numeric IDs:
```python
fory.register_type(Status, type_id=1124725126)
fory.register_union(Wrapper, type_id=1471345060, serializer=WrapperSerializer(fory))
fory.register_type(Envelope, type_id=3022445236)
fory.register_union(Envelope.Detail, type_id=1609214087, serializer=Envelope.DetailSerializer(fory))
fory.register_type(Envelope.Payload, type_id=2862577837)
```
If `option enable_auto_type_id = false;` is set:
```python
fory.register_type(Config, name="myapp.models.Config")
fory.register_union(
Holder,
name="myapp.models.Holder",
serializer=HolderSerializer(fory),
)
```
## Usage
```python
person = Person(name="Alice", pet=Animal.dog(Dog(name="Rex", bark_volume=10)))
data = person.to_bytes()
restored = Person.from_bytes(data)
```
## gRPC Service Companions
With `--grpc`, Python emits `<module>_grpc.py` with stubs, servicer bases, and registration functions. Async `grpc.aio` is the default; `--grpc-python-mode=sync` keeps the same filename and public names. See [Python gRPC](../../grpc/python.md) for dependencies and usage.