This is a standalone PyPI package that provides a thin pybind11 wrapper around
flatbuffers::Parser and GenerateText:
- load
.fbs/.bfbs - JSON -> FlatBuffer binary
- FlatBuffer binary -> JSON (verified against the schema first, so mismatched or corrupt input raises instead of crashing the interpreter)
python -m pip install -U ark-fbscpp/: C++ binding source (pybind11)src/ark_fbs/: Python package wrapper + typing stubstests/: pytest suitethird_party/flatbuffers/: your fork of FlatBuffers as a git submodule (recommended)third_party/nlohmann_json/: single-headernlohmann/json.hpp(required by your FlatBuffers fork)
uv sync --group dev
uv pip install -e .
uv run pytestimport ark_fbs
s = ark_fbs.Schema.from_fbs_text(
"namespace t; table A { x:int; } root_type A;"
)
b = s.json_to_binary('{"x":1}')
print(s.binary_to_json(b))All errors raised by this package derive from ark_fbs.Error, which is itself a
subclass of ValueError:
import ark_fbs
try:
schema.binary_to_json(data)
except ark_fbs.VerifyError:
# data does not match `schema` (stale .fbs?), is truncated, or is corrupt
...
except ark_fbs.SchemaError:
# schema has no root type, etc.
...import ark_fbs
schema = ark_fbs.Schema.from_fbs_file(
"schema.fbs",
include_paths=["./includes", "./third_party/schemas"],
)
data = schema.json_to_binary('{"x": 123}')
print(schema.binary_to_json(data))import ark_fbs
opts = ark_fbs.Options( # keyword-only
strict_json=True,
natural_utf8=True,
defaults_json=True,
size_prefixed=False,
output_enum_identifiers=True,
)
schema = ark_fbs.Schema.from_fbs_text(
"namespace t; table A { x:int; } root_type A;",
options=opts,
root_type_override="A",
)import ark_fbs
schema = ark_fbs.Schema.from_fbs_text("namespace t; table A { x:int; } root_type A;")
bfbs = schema.serialize_schema_bfbs()
schema2 = ark_fbs.Schema.from_bfbs(bfbs)
print(schema2.binary_to_json(schema2.json_to_binary('{"x": 1}')))ark_fbs.Error(ValueError): base class for everything below.ark_fbs.SchemaError(Error): the schema could not be parsed / deserialized, theroot_type_overrideis unknown or names astruct, or an operation needs a root type and none is set.ark_fbs.JsonParseError(Error):json_to_binary()could not parse the JSON text against the schema (includes the parser's line/column message).ark_fbs.VerifyError(Error):binary_to_json()rejected the buffer. Raised when the buffer is too small, itsfile_identifier/ size prefix does not match, it fails FlatBuffers verification against the schema's root type (schema mismatch, truncation, corruption, ormax_depth/max_tablesexceeded), or the JSON generator hit inconsistent data.
Schema.from_fbs_file() raises the usual OSError subclasses
(FileNotFoundError, PermissionError, IsADirectoryError, ...) when the file
cannot be read.
Options(...) controls how schemas are parsed and how JSON/text is emitted.
Constructor (keyword-only):
Options(*, strict_json: bool = True, natural_utf8: bool = True, defaults_json: bool = True, size_prefixed: bool = False, output_enum_identifiers: bool = True)
Fields (all are bool, same defaults as constructor):
strict_json(defaultTrue): Require quoted field names on input and emit quoted field names on output. WithFalsethe emitted text uses unquoted keys and is not valid JSON.natural_utf8(defaultTrue): Emit/interpret UTF-8 in a “natural” way (FlatBuffers option).defaults_json(defaultTrue): Include default scalar values in emitted JSON.size_prefixed(defaultFalse): Data buffers carry a 4-byte size prefix. This affectsjson_to_binary(),binary_to_json()andserialize_schema_bfbs()(the bfbs is size-prefixed too), so use the sameOptionswhen loading a bfbs back withfrom_bfbs().output_enum_identifiers(defaultTrue): Output enum identifiers rather than numeric values.
Schema wraps a flatbuffers::Parser instance plus a cached reflection schema
used for buffer verification.
-
Schema.from_fbs_file(schema_path: str, include_paths: list[str] = [], options: Options = Options(), root_type_override: str = "") -> Schema- schema_path: Path to the
.fbsfile. - include_paths: Extra include directories for
include "foo.fbs"resolution. - options: Parsing/JSON options.
- root_type_override: If non-empty, forces the root type (overrides
root_typein schema). - Raises:
OSError(subclass) if the file cannot be read;SchemaErrorif parsing fails orroot_type_overrideis unknown / not a table.
- schema_path: Path to the
-
Schema.from_fbs_text(schema_text: str, include_paths: list[str] = [], options: Options = Options(), source_filename: str = "", root_type_override: str = "") -> Schema- schema_text: The schema content (as text).
- source_filename: Optional filename used in error messages and for include resolution context.
- Raises:
SchemaErroron parse errors or unknown / non-table root type override.
-
Schema.from_bfbs(bfbs: bytes | bytearray | memoryview, options: Options = Options(), root_type_override: str = "") -> Schema- bfbs: Serialized schema bytes (
.bfbs). Any contiguous buffer-protocol object is accepted. - Raises:
SchemaErrorif deserialization fails orroot_type_overrideis unknown / not a table.
- bfbs: Serialized schema bytes (
-
Schema.json_to_binary(json: str) -> bytes- Parses JSON using the loaded schema and returns the FlatBuffer binary.
- Raises:
JsonParseErrorif JSON parsing fails (including embedded NUL bytes);SchemaErrorif no root type is set.
-
Schema.binary_to_json(data: bytes | bytearray | memoryview, *, verify: bool = True, max_depth: int = 64, max_tables: int = 1_000_000) -> str- Converts a FlatBuffer binary (for the schema's root type) to JSON text. Any contiguous buffer-protocol object is accepted without copying.
- verify: Run the FlatBuffers verifier against the root type before
generating text. Leave this on unless the buffer is known-good and you have
measured that verification matters; with
verify=Falsea mismatched or corrupt buffer is undefined behaviour and can crash the interpreter. - max_depth / max_tables: Verifier limits on nesting depth and total
table count. Very large data files can exceed the default table limit;
raise
max_tablesin that case. - Raises:
VerifyErrorif the buffer fails verification or conversion fails;SchemaErrorif no root type is set;TypeErrorifdatais not a contiguous byte buffer.
-
Schema.serialize_schema_bfbs() -> bytes- Returns the loaded schema serialized as
.bfbsbytes (cached at construction). - Raises:
SchemaErrorif the schema is not initialized.
- Returns the loaded schema serialized as
Schema.root_type: str— name of the current root table, or""if none.Schema.file_identifier: str— the schema'sfile_identifier, or""if none. When non-empty,binary_to_json()requires buffers to carry it.
Schema.json_to_binary() and Schema.binary_to_json() require a root type. You must either:
- Provide
root_typein the schema (root_type A;), or - Pass
root_type_override="A"when constructing theSchema.
The root type must be a table; a struct is rejected with SchemaError.
A Schema instance is not safe for concurrent use from multiple threads
(json_to_binary() reuses an internal builder). Create one Schema per thread
or guard calls with a lock.
CI uses cibuildwheel to produce wheels for multiple CPython versions and
architectures. See .github/workflows/wheels.yml. The pytest suite runs on
Linux/macOS/Windows via .github/workflows/tests.yml.