Skip to content
Pyrula
Pre-release: the packages are not on PyPI yet, so pip install does not resolve. Build from source to try it today.

Core

Generated from the type stubs and docstrings. Do not edit by hand.

Avro serde with Confluent Schema Registry integration.

Wire format: [0x00 magic][schema_id: 4 bytes BE][avro payload]

Schema registration is lazy (happens on first serialize() call). Reader schemas are fetched from the registry on first deserialize() per schema ID and cached for the serde’s lifetime.

TLS/mTLS: pass ca_path to trust a custom CA, or cert_path + key_path for mutual TLS (both required together; applies only when registry_url is https://). Encrypted private keys are not supported - key_path must point to an unencrypted PEM.

reader_schema: the schema every record is resolved INTO on deserialize (standard Avro schema resolution); without one a record decodes to its own writer schema’s shape, fetched by the id in its framing.

logical_types and strict: as for AvroSerde. See the docsite for a usage example including mTLS setup.

timeout_ms: the bound on one registry HTTP request, from connect to the last byte of the response (default 5000, 1 to 300000; ValueError otherwise). A call that makes one request fails within about this long when the registry is down or silent. A failed lookup, including a 404 for an unknown schema id, is remembered for 5 seconds, so records that need the same schema do not each ask the registry again; a registry follower that is behind on a brand-new id keeps that id failing for up to 5 seconds. A batch asks for each schema id at most once and, once the registry is unreachable or answers 5xx, makes no further requests; records that needed one fail with that error.

AvroRegistrySerde(registry_url: str, subject: str, schema: str, username: Optional[str] = None, password: Optional[str] = None, ca_path: Optional[str] = None, cert_path: Optional[str] = None, key_path: Optional[str] = None, reader_schema: Optional[str] = None, *, logical_types: Literal['python', 'raw'] = 'python', strict: bool = False, timeout_ms: int = 5000)
for_topic(registry_url: str, topic: str, schema: str, is_key: bool = False, username: Optional[str] = None, password: Optional[str] = None, ca_path: Optional[str] = None, cert_path: Optional[str] = None, key_path: Optional[str] = None, reader_schema: Optional[str] = None, *, logical_types: Literal['python', 'raw'] = 'python', strict: bool = False, timeout_ms: int = 5000) -> AvroRegistrySerde
register(self) -> Ok[int] | Err[SerdeError]
subject(self) -> str
serialize(self, obj: Any) -> Ok[bytes] | Err[SerdeError]
deserialize(self, data: bytes) -> Ok[Any] | Err[SerdeError]
serialize_many(self, items: Iterable[Any]) -> IList
serialize_many_bytes(self, items: Iterable[Any]) -> BytesList
deserialize_many(self, bytes_list: Iterable[bytes] | BytesList) -> IList
deserialize_many_objects(self, bytes_list: Iterable[bytes] | BytesList) -> IList
deserialize_many_from_packed(self, packed: bytes, count: int) -> IList
check_compatibility(self, schema: str, version: Optional[str] = None) -> Ok[bool] | Err[SerdeError]
list_versions(self) -> Ok[list[int]] | Err[SerdeError]
get_schema_by_version(self, version: int) -> Ok[str] | Err[SerdeError]
delete_version(self, version: int) -> Ok[bool] | Err[SerdeError]

Avro serde over a single schema, returning Either instead of raising.

Logical types convert as fastavro (and so confluent-kafka) converts them: timestamp-* to an aware UTC datetime, local-timestamp-* to a naive datetime, date to a date, time-* to a time, decimal to a Decimal, uuid to a UUID. Writing takes those types or the plain value on the wire.

logical_types: “raw” decodes logical types to their value on the wire instead - int, bytes or str. Encoding takes either form whichever is chosen.

strict: refuse what fastavro converts by guessing - a naive datetime for a timestamp-* (fastavro takes it as the host’s local time), a datetime for a date (fastavro drops its time), and a decoded decimal with more digits than its precision (fastavro rounds it).

AvroSerde(schema_json: str, *, logical_types: Literal['python', 'raw'] = 'python', strict: bool = False)
serialize(self, obj: Any) -> Ok[bytes] | Err[SerdeError]
deserialize(self, data: bytes) -> Ok[Any] | Err[SerdeError]
serialize_many(self, items: Iterable[Any]) -> IList
serialize_many_bytes(self, items: Iterable[Any]) -> BytesList
deserialize_many(self, bytes_list: Iterable[bytes] | BytesList) -> IList

BytesList(items: Any = ...)
empty(cls) -> BytesList
from_packed(buf: bytes, count: int) -> BytesList
get(self, index: int) -> Some[bytes] | _Nothing
append(self, item: bytes) -> BytesList
to_list(self) -> list[bytes]
to_packed(self) -> bytes
to_ilist(self) -> IList[bytes]
length(self) -> int
is_empty(self) -> bool
index(self, value: Any, start: int = 0, stop: int = ...) -> int
count(self, value: Any) -> int


A typed time-span value backed by an i64 nanosecond count.

Mirrors Scala’s FiniteDuration - a precise, immutable quantity of time with unit-converting constructors and full arithmetic support.

nanos(n: int) -> Duration
micros(n: int) -> Duration
millis(n: int) -> Duration
seconds(n: float) -> Duration
minutes(n: float) -> Duration
hours(n: float) -> Duration
days(n: float) -> Duration
from_timedelta(td: Any) -> Duration
to_nanos(self) -> int
to_millis(self) -> int
to_seconds(self) -> float
to_timedelta(self) -> Any

A value (Ok) or an error (Err). Subclassed by Ok and Err, the same way Scala’s Either is by Right/Left, so Either[A, E] is a real generic and isinstance(x, Either) holds for both. Abstract: build values through the factories below (or Ok/Err directly), not Either(...).

ok(value: T) -> Ok[T]
err(error: E) -> Err[E]
try_of(f: Callable[[], T]) -> Either[T, Exception]
cond(condition: bool, ok: T, err: E) -> Either[T, E]
sequence(values: Iterable[Either[T, E]]) -> Either[list[T], E]
traverse(values: Iterable[_A], fn: Callable[[_A], Either[U, F]]) -> Either[list[U], F]
map(self, f: Callable[..., Any]) -> Either[Any, E]
flat_map(self, f: Callable[..., Any]) -> Either[Any, E]
map_err(self, f: Callable[..., Any]) -> Either[T, Any]
ensure(self, predicate: Callable[[T], bool], error: Callable[[T], F]) -> Either[T, E | F]
ensure(self, predicate: Callable[[T], bool], error: F) -> Either[T, E | F]
tap(self, fn: Callable[[T], Any]) -> Either[T, E]
tap_err(self, fn: Callable[[E], Any]) -> Either[T, E]
flatten(self: Either[Ok[U], E]) -> Either[U, E]
flatten(self: Either[Err[F], E]) -> Err[E | F]
flatten(self: Either[Either[U, F], E]) -> Either[U, E | F]
bimap(self, err_fn: Callable[[E], F], ok_fn: Callable[[T], U]) -> Either[U, F]
recover(self, f: Callable[[E], Any]) -> Either[Any, Any]
recover_with(self, f: Callable[[E], Either[Any, Any]]) -> Either[Any, Any]
or_else(self, alt: Either[Any, Any] | Callable[[], Either[Any, Any]]) -> Either[Any, Any]
fold(self, err: Callable[..., Any], ok: Callable[..., Any]) -> Any
get_or_else(self, default: Any) -> Any
get_or_else_with(self, factory: Callable[[], U]) -> T | U
unwrap_or_raise(self, exc: Any = None) -> Any
to_option(self) -> Option[T]
is_ok(self) -> bool
is_err(self) -> bool

Err(error: E)

Fields:

  • error: E
map(self, f: Callable[..., Any]) -> Err[E]
flat_map(self, f: Callable[..., Any]) -> Err[E]
recover(self, f: Callable[[E], Any]) -> Either[Any, Any]
recover_with(self, f: Callable[[E], Either[Any, Any]]) -> Either[Any, Any]
map_err(self, f: Callable[..., Any]) -> Err[Any]
ensure(self, predicate: Callable[[Any], bool], error: F | Callable[[Any], F]) -> Err[E]
tap(self, fn: Callable[[Any], Any]) -> Err[E]
tap_err(self, fn: Callable[[E], Any]) -> Err[E]
flatten(self) -> Err[E]
bimap(self, err_fn: Callable[[E], F], ok_fn: Callable[[Any], U]) -> Err[F]
or_else(self, alt: Either[Any, Any] | Callable[[], Either[Any, Any]]) -> Either[Any, Any]
fold(self, err: Callable[..., Any], ok: Callable[..., Any]) -> Any
get_or_else(self, default: Any) -> Any
get_or_else_with(self, factory: Callable[[], U]) -> U
unwrap_or_raise(self, exc: Any = None) -> Any
to_option(self) -> _Nothing
is_ok(self) -> bool
is_err(self) -> bool

Failure(error: BaseException)

Fields:

  • error: BaseException
map(self, f: Callable[..., Any]) -> Failure
flat_map(self, f: Callable[..., Any]) -> Failure
tap(self, fn: Callable[[Any], Any]) -> Failure
tap_failure(self, fn: Callable[[BaseException], Any]) -> Failure
flatten(self) -> Failure
recover(self, f: Callable[[Any], Any]) -> Try[Any]
recover_with(self, f: Callable[[Any], Try[Any]]) -> Try[Any]
or_else(self, alt: Try[Any] | Callable[[], Try[Any]]) -> Try[Any]
fold(self, failure: Callable[..., Any], success: Callable[..., Any]) -> Any
get_or_else(self, default: Any) -> Any
get_or_else_with(self, factory: Callable[[], U]) -> U
to_either(self) -> Err[Any]
is_success(self) -> bool
is_failure(self) -> bool

FloatList(items: Any = ...)
empty(cls) -> FloatList
map_float(self, f: Callable[[float], float]) -> FloatList
filter(self, pred: Callable[[float], bool]) -> FloatList
fold_left(self, initial: Any, f: Callable[..., Any]) -> Any
add_scalar(self, n: float) -> FloatList
sub_scalar(self, n: float) -> FloatList
mul_scalar(self, n: float) -> FloatList
div_scalar(self, n: float) -> FloatList
abs_vals(self) -> FloatList
clamp_vals(self, lo: float, hi: float) -> FloatList
zip_add(self, other: FloatList) -> FloatList
zip_mul(self, other: FloatList) -> FloatList
sum(self) -> float
min(self) -> float
max(self) -> float
mean(self) -> float
std_dev(self) -> float
to_list(self) -> list[float]
to_ilist(self) -> IList[float]
length(self) -> int
is_empty(self) -> bool
index(self, value: Any, start: int = 0, stop: int = ...) -> int
count(self, value: Any) -> int

IList(items: Any = ...)
empty(cls) -> IList[Any]
map(self, f: Callable[..., Any]) -> IList[Any]
flat_map(self, f: Callable[..., Any]) -> IList[Any]
filter(self, pred: Callable[..., bool]) -> IList[T]
fold_left(self, initial: Any, f: Callable[..., Any]) -> Any
head(self) -> Some[T] | _Nothing
last(self) -> Some[T] | _Nothing
tail(self) -> IList[T]
find(self, pred: Callable[..., bool]) -> Some[T] | _Nothing
take(self, n: int) -> IList[T]
drop(self, n: int) -> IList[T]
distinct(self) -> IList[T]
zip(self, other: IList[Any]) -> IList[tuple[T, Any]]
append(self, item: T) -> IList[T]
prepend(self, item: T) -> IList[T]
concat(self, other: IList[T]) -> IList[T]
to_list(self) -> list[T]
collect_ok(self) -> IList[Any]
collect_err(self) -> IList[Any]
partition_either(self) -> tuple[IList[Any], IList[Any]]
length(self) -> int
is_empty(self) -> bool
index(self, value: Any, start: int = 0, stop: int = ...) -> int
count(self, value: Any) -> int

Keys are found as in a dict: placed by Python’s hash() and compared with ==, so any key equal to a stored one finds it, whatever its type.

An IMap iterates in a fixed order that depends only on its contents, not on insertion order, the process or PYTHONHASHSEED, when every key is an exact str or bytes, an int, float, bool or None, or a tuple or frozenset of those. The order is by a 64-bit value computed from each key’s content, on first iteration, and it is neither insertion order nor sorted order. A key that hashes by identity (a plain object), through a str (a plain Enum member), or a str or bytes subclass with its own hash, iterates in a process-dependent order, and NaN keys with identical bits, or distinct keys of another type that share a hash, stay in insertion order among themselves.

IMap(items: Any = ...)
empty(cls) -> IMap[Any, Any]
get(self, key: object, /) -> Optional[V]
get(self, key: object, default: V, /) -> V
get(self, key: object, default: _T, /) -> V | _T
get_option(self, key: K) -> Some[V] | _Nothing
set(self, key: K, value: V) -> IMap[K, V]
remove(self, key: K) -> IMap[K, V]
contains(self, key: K) -> bool
to_dict(self) -> dict
keys(self) -> KeysView[K]
values(self) -> ValuesView[V]
items(self) -> ItemsView[K, V]
map_values(self, f: Callable[[V], Any]) -> IMap[K, Any]
filter_values(self, pred: Callable[[V], bool]) -> IMap[K, V]
merge(self, other: IMap[K, V]) -> IMap[K, V]
length(self) -> int
is_empty(self) -> bool

Keys are found as in a frozenset: placed by Python’s hash() and compared with ==, so any key equal to a stored one finds it, whatever its type.

An ISet iterates in a fixed order that depends only on its contents, not on insertion order, the process or PYTHONHASHSEED, when every key is an exact str or bytes, an int, float, bool or None, or a tuple or frozenset of those. The order is by a 64-bit value computed from each key’s content, on first iteration, and it is neither insertion order nor sorted order. A key that hashes by identity (a plain object), through a str (a plain Enum member), or a str or bytes subclass with its own hash, iterates in a process-dependent order, and NaN keys with identical bits, or distinct keys of another type that share a hash, stay in insertion order among themselves.

ISet(items: Optional[Iterable[T]] = None)
empty(cls) -> ISet[Any]
add(self, item: T) -> ISet[T]
remove(self, item: T) -> ISet[T]
contains(self, item: T) -> bool
union(self, other: ISet[T]) -> ISet[T]
intersection(self, other: ISet[T]) -> ISet[T]
difference(self, other: ISet[T]) -> ISet[T]
is_subset_of(self, other: ISet[T]) -> bool
map(self, f: Callable[[T], Any]) -> ISet[Any]
filter(self, pred: Callable[[T], bool]) -> ISet[T]
to_set(self) -> set[T]
to_ilist(self) -> IList[T]
size(self) -> int
is_empty(self) -> bool
isdisjoint(self, other: Iterable[Any]) -> bool

IntList(items: Any = ...)
empty(cls) -> IntList
map_int(self, f: Callable[[int], int]) -> IntList
filter(self, pred: Callable[[int], bool]) -> IntList
fold_left(self, initial: Any, f: Callable[..., Any]) -> Any
add_scalar(self, n: int) -> IntList
sub_scalar(self, n: int) -> IntList
mul_scalar(self, n: int) -> IntList
div_scalar(self, n: int) -> IntList
abs_vals(self) -> IntList
clamp_vals(self, lo: int, hi: int) -> IntList
zip_add(self, other: IntList) -> IntList
zip_mul(self, other: IntList) -> IntList
sum(self) -> int
min(self) -> int
max(self) -> int
mean(self) -> float
std_dev(self) -> float
to_list(self) -> list[int]
to_ilist(self) -> IList[int]
length(self) -> int
is_empty(self) -> bool
index(self, value: Any, start: int = 0, stop: int = ...) -> int
count(self, value: Any) -> int

IntSet(items: Any = ...)
empty(cls) -> IntSet
add(self, value: int) -> IntSet
remove(self, value: int) -> IntSet
contains(self, value: Any) -> bool
union(self, other: IntSet) -> IntSet
intersection(self, other: IntSet) -> IntSet
difference(self, other: IntSet) -> IntSet
symmetric_difference(self, other: IntSet) -> IntSet
is_subset(self, other: IntSet) -> bool
is_disjoint(self, other: IntSet) -> bool
cardinality(self) -> int
to_list(self) -> list[int]
to_bytes(self) -> bytes
from_bytes(data: bytes) -> IntSet
is_empty(self) -> bool
isdisjoint(self, other: Iterable[Any]) -> bool

Invalid(error: E)

Fields:

  • errors: tuple[E, ...]
sequence(values: Iterable[Validated[U, F]]) -> Validated[list[U], F]
traverse(values: Iterable[_A], fn: Callable[[_A], Validated[U, F]]) -> Validated[list[U], F]

JSON Schema serde with Confluent Schema Registry integration.

Wire format: [0x00 magic][schema_id: 4 bytes BE][json payload]

Same magic byte as Avro; content is JSON. NOTE: payloads are NOT validated against the JSON Schema - this serde provides Confluent wire framing ([0x00][schema_id:4B BE][json]) and registry registration only. (confluent’s JSONSerializer validates; pyrula does not yet.)

timeout_ms: the bound on one registry HTTP request, from connect to the last byte of the response (default 5000, 1 to 300000; ValueError otherwise). A failed registration is remembered for 5 seconds, so serializing many records against a registry that is down makes one request, not one per record; register() always asks again.

JsonSchemaRegistrySerde(registry_url: str, subject: str, schema: str, username: Optional[str] = None, password: Optional[str] = None, ca_path: Optional[str] = None, cert_path: Optional[str] = None, key_path: Optional[str] = None, *, timeout_ms: int = 5000)
for_topic(registry_url: str, topic: str, schema: str, is_key: bool = False, username: Optional[str] = None, password: Optional[str] = None, ca_path: Optional[str] = None, cert_path: Optional[str] = None, key_path: Optional[str] = None, *, timeout_ms: int = 5000) -> JsonSchemaRegistrySerde
register(self) -> Ok[int] | Err[SerdeError]
subject(self) -> str
serialize(self, obj: Any) -> Ok[bytes] | Err[SerdeError]
deserialize(self, data: bytes) -> Ok[Any] | Err[SerdeError]
serialize_many(self, items: Iterable[Any]) -> IList
serialize_many_bytes(self, items: Iterable[Any]) -> BytesList
deserialize_many(self, bytes_list: Iterable[bytes] | BytesList) -> IList
deserialize_many_objects(self, bytes_list: Iterable[bytes] | BytesList) -> IList
deserialize_many_from_packed(self, packed: bytes, count: int) -> IList
check_compatibility(self, schema: str, version: Optional[str] = None) -> Ok[bool] | Err[SerdeError]
list_versions(self) -> Ok[list[int]] | Err[SerdeError]
get_schema_by_version(self, version: int) -> Ok[str] | Err[SerdeError]
delete_version(self, version: int) -> Ok[bool] | Err[SerdeError]

JsonSerde()
serialize(self, obj: Any) -> Ok[bytes] | Err[SerdeError]
deserialize(self, data: bytes) -> Ok[Any] | Err[SerdeError]
serialize_many(self, items: Iterable[Any]) -> IList
serialize_many_raw(self, items: Iterable[Any]) -> BytesList
deserialize_many(self, bytes_list: Iterable[bytes] | BytesList) -> IList
deserialize_many_raw(self, bytes_list: Iterable[bytes] | BytesList) -> IList

A list with at least one element.

head, last, and reduce are total - they return T, not Option[T], because the non-empty invariant is enforced at construction time. from_list is the safe boundary: it returns Option[NonEmptyList[T]].

NonEmptyList(head: T, *tail: T)
of(head: T, *tail: T) -> NonEmptyList[T]
from_list(items: IList[T] | list[T]) -> Option[NonEmptyList[T]]
head(self) -> T
tail(self) -> IList[T]
last(self) -> T
map(self, f: Callable[[T], Any]) -> NonEmptyList[Any]
flat_map(self, f: Callable[[T], NonEmptyList[Any]]) -> NonEmptyList[Any]
reduce(self, f: Callable[[T, T], T]) -> T
fold_left(self, init: Any, f: Callable[[Any, T], Any]) -> Any
append(self, item: T) -> NonEmptyList[T]
prepend(self, item: T) -> NonEmptyList[T]
to_ilist(self) -> IList[T]
to_list(self) -> list[T]
length(self) -> int
index(self, value: Any, start: int = 0, stop: int = ...) -> int
count(self, value: Any) -> int

Ok(value: T)

Fields:

  • value: T
map(self, f: Callable[..., Any]) -> Ok[Any]
flat_map(self, f: Callable[..., Any]) -> Any
map_err(self, f: Callable[..., Any]) -> Ok[T]
ensure(self, predicate: Callable[[T], bool], error: Callable[[T], F]) -> Either[T, F]
ensure(self, predicate: Callable[[T], bool], error: F) -> Either[T, F]
tap(self, fn: Callable[[T], Any]) -> Ok[T]
tap_err(self, fn: Callable[[Any], Any]) -> Ok[T]
flatten(self: Ok[_EitherResult]) -> _EitherResult
bimap(self, err_fn: Callable[[Any], F], ok_fn: Callable[[T], U]) -> Ok[U]
recover(self, f: Callable[[Any], Any]) -> Ok[T]
recover_with(self, f: Callable[[Any], Either[Any, Any]]) -> Ok[T]
or_else(self, alt: Either[Any, Any] | Callable[[], Either[Any, Any]]) -> Ok[T]
fold(self, err: Callable[..., Any], ok: Callable[..., Any]) -> Any
get_or_else(self, default: Any) -> T
get_or_else_with(self, factory: Callable[[], U]) -> T
unwrap_or_raise(self, exc: Any = None) -> T
to_option(self) -> Some[T]
is_ok(self) -> bool
is_err(self) -> bool

Some(value) or Nothing; subclassed by both like Scala’s Option.

of(value: Optional[T]) -> Option[T]
when(condition: bool, value: T) -> Option[T]
from_callable(f: Callable[[], T]) -> Option[T]
sequence(values: Iterable[Option[T]]) -> Option[list[T]]
traverse(values: Iterable[_A], fn: Callable[[_A], Option[U]]) -> Option[list[U]]
map(self, f: Callable[..., Any]) -> Option[Any]
flat_map(self, f: Callable[..., Any]) -> Option[Any]
tap(self, fn: Callable[[T], Any]) -> Option[T]
flatten(self: Option[Some[U]]) -> Option[U]
flatten(self: Option[_Nothing]) -> _Nothing
flatten(self: Option[Option[U]]) -> Option[U]
filter(self, pred: Callable[..., bool]) -> Option[T]
get_or_else(self, default: Any) -> Any
get_or_else_with(self, factory: Callable[[], U]) -> T | U
or_else(self, alt: Option[Any] | Callable[[], Option[Any]]) -> Option[Any]
fold(self, nothing_val: Any, some_fn: Callable[..., Any]) -> Any
to_either(self, left: Any) -> Either[T, Any]
to_either_with(self, error_factory: Callable[[], E]) -> Either[T, E]
to_list(self) -> IList[T]
is_some(self) -> bool
is_nothing(self) -> bool
is_empty(self) -> bool

Protobuf serde with Confluent Schema Registry integration.

Wire format: [0x00 magic][schema_id: 4 bytes BE][msg-index zigzag varint array][protobuf payload]

Accepts a serialized FileDescriptorSet and a fully-qualified message name. Deserialization decodes to Python dicts using prost-reflect; no compiled message types needed. Registration requires proto_source (the .proto source text) so the Confluent SR can parse and validate the schema.

LIMITATION: the Confluent message-index is always written as [0] (first message) - only correct when message_name is the first top-level message; multi-message/nested .proto files will not interoperate with Confluent consumers that rely on the message index.

NOTE: proto3 implicit-presence scalar fields at their default are omitted on deserialize, absent from the returned dict (standard protobuf semantics). NOTE: enum fields accept the enum value name (str) or number (int) on serialize; deserialize returns the number (int).

timeout_ms: the bound on one registry HTTP request, from connect to the last byte of the response (default 5000, 1 to 300000; ValueError otherwise). A failed registration is remembered for 5 seconds, so serializing many records against a registry that is down makes one request, not one per record; register() always asks again.

ProtobufRegistrySerde(registry_url: str, subject: str, file_descriptor_set: bytes, message_name: str, proto_source: Optional[str] = None, username: Optional[str] = None, password: Optional[str] = None, ca_path: Optional[str] = None, cert_path: Optional[str] = None, key_path: Optional[str] = None, *, timeout_ms: int = 5000)
for_topic(registry_url: str, topic: str, file_descriptor_set: bytes, message_name: str, is_key: bool = False, proto_source: Optional[str] = None, username: Optional[str] = None, password: Optional[str] = None, ca_path: Optional[str] = None, cert_path: Optional[str] = None, key_path: Optional[str] = None, *, timeout_ms: int = 5000) -> ProtobufRegistrySerde
register(self) -> Ok[int] | Err[SerdeError]
subject(self) -> str
serialize(self, obj: Any) -> Ok[bytes] | Err[SerdeError]
serialize_with_id(self, obj: Any, schema_id: int) -> Ok[bytes] | Err[SerdeError]
deserialize(self, data: bytes) -> Ok[Any] | Err[SerdeError]
serialize_many(self, items: Iterable[Any]) -> IList
serialize_many_bytes(self, items: Iterable[Any]) -> BytesList
deserialize_many(self, bytes_list: Iterable[bytes] | BytesList) -> IList
deserialize_many_objects(self, bytes_list: Iterable[bytes] | BytesList) -> IList
deserialize_many_from_packed(self, packed: bytes, count: int) -> IList
check_compatibility(self, proto_source: str, version: Optional[str] = None) -> Ok[bool] | Err[SerdeError]
list_versions(self) -> Ok[list[int]] | Err[SerdeError]
get_schema_by_version(self, version: int) -> Ok[str] | Err[SerdeError]
delete_version(self, version: int) -> Ok[bool] | Err[SerdeError]

A journaled exception that could not be rebuilt as its original class.

type_path is the original module:qualname and message its text; str() is the message, and serializing it again writes the original pair.

RecordedError(type_path: str, message: str)

Fields:

  • type_path: str
  • message: str



Some(value: T)

Fields:

  • value: T
map(self, f: Callable[..., Any]) -> Some[Any]
flat_map(self, f: Callable[..., Any]) -> Any
tap(self, fn: Callable[[T], Any]) -> Some[T]
flatten(self: Some[_OptionResult]) -> _OptionResult
filter(self, pred: Callable[..., bool]) -> Any
get_or_else(self, default: Any) -> T
get_or_else_with(self, factory: Callable[[], U]) -> T
or_else(self, alt: Option[Any] | Callable[[], Option[Any]]) -> Some[T]
fold(self, nothing_val: Any, some_fn: Callable[..., Any]) -> Any
to_either(self, left: Any) -> Ok[T]
to_either_with(self, error_factory: Callable[[], E]) -> Ok[T]
to_list(self) -> IList[T]
is_some(self) -> bool
is_nothing(self) -> bool
is_empty(self) -> bool

Success(value: T)

Fields:

  • value: T
map(self, f: Callable[..., Any]) -> Any
flat_map(self, f: Callable[..., Any]) -> Any
tap(self, fn: Callable[[T], Any]) -> Success[T]
tap_failure(self, fn: Callable[[BaseException], Any]) -> Success[T]
flatten(self: Success[_TryResult]) -> _TryResult
recover(self, f: Callable[[Any], Any]) -> Success[T]
recover_with(self, f: Callable[[Any], Try[Any]]) -> Success[T]
or_else(self, alt: Try[Any] | Callable[[], Try[Any]]) -> Success[T]
fold(self, failure: Callable[..., Any], success: Callable[..., Any]) -> Any
get_or_else(self, default: Any) -> T
get_or_else_with(self, factory: Callable[[], U]) -> T
to_either(self) -> Ok[T]
is_success(self) -> bool
is_failure(self) -> bool

Success(value) or Failure(exc); subclassed by both like Scala’s Try.

apply(f: Callable[[], T]) -> Try[T]
of(f: Callable[[], T]) -> Try[T]
sequence(values: Iterable[Try[T]]) -> Try[list[T]]
traverse(values: Iterable[_A], fn: Callable[[_A], Try[U]]) -> Try[list[U]]
map(self, f: Callable[..., Any]) -> Try[Any]
flat_map(self, f: Callable[..., Any]) -> Try[Any]
tap(self, fn: Callable[[T], Any]) -> Try[T]
tap_failure(self, fn: Callable[[BaseException], Any]) -> Try[T]
flatten(self: Try[Success[U]]) -> Try[U]
flatten(self: Try[Failure]) -> Failure
flatten(self: Try[Try[U]]) -> Try[U]
recover(self, f: Callable[[Any], Any]) -> Try[Any]
recover_with(self, f: Callable[[Any], Try[Any]]) -> Try[Any]
or_else(self, alt: Try[Any] | Callable[[], Try[Any]]) -> Try[Any]
fold(self, failure: Callable[..., Any], success: Callable[..., Any]) -> Any
get_or_else(self, default: Any) -> Any
get_or_else_with(self, factory: Callable[[], U]) -> T | U
to_either(self) -> Either[T, Any]
is_success(self) -> bool
is_failure(self) -> bool

Valid(value: T)

Fields:

  • value: T
sequence(values: Iterable[Validated[U, F]]) -> Validated[list[U], F]
traverse(values: Iterable[_A], fn: Callable[[_A], Validated[U, F]]) -> Validated[list[U], F]

Like Either, but zip accumulates errors instead of short-circuiting.

valid(value: T) -> Validated[T, E]
invalid(error: E) -> Validated[T, E]
from_either(either: Either[T, E]) -> Validated[T, E]
cond(condition: bool, value: T, error: E) -> Validated[T, E]
sequence(values: Iterable[Validated[U, F]]) -> Validated[list[U], F]
traverse(values: Iterable[_A], fn: Callable[[_A], Validated[U, F]]) -> Validated[list[U], F]
map(self, f: Callable[[T], Any]) -> Validated[Any, E]
map_err(self, f: Callable[[tuple[E, ...]], Any]) -> Validated[T, Any]
zip(self, other: Validated[Any, E]) -> Validated[Any, E]
fold(self, invalid: Callable[[tuple[E, ...]], Any], valid: Callable[[T], Any]) -> Any
get_or_else(self, default: T) -> T
to_either(self) -> Either[T, tuple[E, ...]]
is_valid(self) -> bool
is_invalid(self) -> bool
  • Nothing: _Nothing = _nothing()
case(cls: type[T]) -> type[T]

Make cls a frozen dataclass. Use dataclasses.replace and dataclasses.asdict.

do(func: Callable[..., Any]) -> Callable[..., Any]
do_async(func: Callable[..., Any]) -> Callable[..., Any]
flow(*funcs: Callable[..., Any]) -> Callable[..., Any]

Compose funcs left to right into a single callable.

match(value: Any) -> Callable[..., Any]

match(value)(on(T1, h1), on(T2, h2), ...): dispatch to the first matching handler. For a @sealed hierarchy, raises if any concrete case is uncovered.

newtype(name: str, base_type: type[T]) -> type[T]

A lightweight subclass of base_type named name, for a distinct domain type.

newtype_strict(name: str, base_type: type[T], *, validate: Optional[Callable[..., bool]] = None, err_msg: Optional[str] = None) -> type[T]

Like newtype, but raises on construction if validate rejects the value.

on(typ: type[T], handler: Callable[..., Any]) -> Any

Build a match arm: dispatch to handler when the value is an instance of typ.

partial(f: Callable[..., Any], *args: Any, **kwargs: Any) -> Callable[..., Any]
pipe(value: Any, *funcs: Callable[..., Any]) -> Any

Thread value through funcs left to right, each result feeding the next.

sealed(cls: type[T]) -> type[T]

Mark cls as a closed hierarchy: match enforces exhaustiveness over its cases.

Subclasses may be declared only in the module that defines cls; any other module gets a TypeError at class creation.

View this page as Markdown