pyfury 0.10.3
Apache Fury™(incubating) is a blazingly fast multi-language serialization framework powered by jit and zero-copy
Keywords: fury, serialization, multi-language, fast, row-format, jit, codegen, polymorphic, zero-copy

# Apache Fury™ Python

Apache Fury(incubating) is a blazingly-fast multi-language serialization framework powered by just-in-time compilation and zero-copy.

## Important Announcement

Starting from v0.11.0, Apache Fury has been renamed to [Apache Fory](https://github.com/apache/fory). Please use [pyfory](https://pypi.org/project/pyfory/) for the latest version.

For versions before 0.11, continue using "fury" in package names, imports, and dependencies. Refer to the [Fury Docs](https://fory.apache.org/docs/0.10/docs/introduction/) for usage instructions in older versions.

For more details about the renaming, please visit https://fory.apache.org/blog/fury_renamed_to_fory

## Install Pyfury

For version 0.11 and later:

```
pip install pyfory
```

For versions before 0.11:

```
pip install pyfury
```

## Getting Started

### Object graph serialization

```python
from dataclasses import dataclass
import pyfory

class Foo:
    name: str:
    age: int
pyfory.register(Foo)
bytes = pyfory.serialize(Foo("Shawn", 30))  # Ultra-fast encoding
restored = pyfory.deserialize(bytes)  # Instant decoding
```

### Row format zero-copy serialization

```java
public class Bar {
  String f1;
  List<Long> f2;
}

public class Foo {
  int f1;
  List<Integer> f2;
  Map<String, Integer> f3;
  List<Bar> f4;
}

RowEncoder<Foo> encoder = Encoders.bean(Foo.class);
Foo foo = new Foo();
foo.f1 = 10;
foo.f2 = IntStream.range(0, 1000000).boxed().collect(Collectors.toList());
foo.f3 = IntStream.range(0, 1000000).boxed().collect(Collectors.toMap(i -> "k"+i, i->i));
List<Bar> bars = new ArrayList<>(1000000);
for (int i = 0; i < 1000000; i++) {
  Bar bar = new Bar();
  bar.f1 = "s"+i;
  bar.f2 = LongStream.range(0, 10).boxed().collect(Collectors.toList());
  bars.add(bar);
}
foo.f4 = bars;
// Can be zero-copy read by python
BinaryRow binaryRow = encoder.toRow(foo);
// can be data from python
Foo newFoo = encoder.fromRow(binaryRow);
// zero-copy read List<Integer> f2
BinaryArray binaryArray2 = binaryRow.getArray(1);
// zero-copy read List<Bar> f4
BinaryArray binaryArray4 = binaryRow.getArray(3);
// zero-copy read 11th element of `readList<Bar> f4`
BinaryRow barStruct = binaryArray4.getStruct(10);

// zero-copy read 6th of f2 of 11th element of `readList<Bar> f4`
barStruct.getArray(1).getInt64(5);
RowEncoder<Bar> barEncoder = Encoders.bean(Bar.class);
// deserialize part of data.
Bar newBar = barEncoder.fromRow(barStruct);
Bar newBar2 = barEncoder.fromRow(binaryArray4.getStruct(20));
```

### Python

```python
@dataclass
class Bar:
    f1: str
    f2: List[pa.int64]
@dataclass
class Foo:
    f1: pa.int32
    f2: List[pa.int32]
    f3: Dict[str, pa.int32]
    f4: List[Bar]

encoder = pyfury.encoder(Foo)
foo = Foo(f1=10, f2=list(range(1000_000)),
         f3={f"k{i}": i for i in range(1000_000)},
         f4=[Bar(f1=f"s{i}", f2=list(range(10))) for i in range(1000_000)])
binary: bytes = encoder.to_row(foo).to_bytes()
foo_row = pyfury.RowData(encoder.schema, binary)
print(foo_row.f2[100000], foo_row.f4[100000].f1, foo_row.f4[200000].f2[5])
```