Skip to content

Repository files navigation

Ark FBS

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)

Installation

Install from PyPI

python -m pip install -U ark-fbs

Repo layout

  • cpp/: C++ binding source (pybind11)
  • src/ark_fbs/: Python package wrapper + typing stubs
  • tests/: pytest suite
  • third_party/flatbuffers/: your fork of FlatBuffers as a git submodule (recommended)
  • third_party/nlohmann_json/: single-header nlohmann/json.hpp (required by your FlatBuffers fork)

Local build (editable)

uv sync --group dev
uv pip install -e .
uv run pytest

Usage

import 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))

Error handling

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.
    ...

Load from a .fbs file (with include paths)

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))

Options and root type override

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",
)

Load from .bfbs (serialized schema)

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}')))

API Reference

Exceptions

  • ark_fbs.Error(ValueError): base class for everything below.
  • ark_fbs.SchemaError(Error): the schema could not be parsed / deserialized, the root_type_override is unknown or names a struct, 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, its file_identifier / size prefix does not match, it fails FlatBuffers verification against the schema's root type (schema mismatch, truncation, corruption, or max_depth / max_tables exceeded), 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.

ark_fbs.Options

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 (default True): Require quoted field names on input and emit quoted field names on output. With False the emitted text uses unquoted keys and is not valid JSON.
  • natural_utf8 (default True): Emit/interpret UTF-8 in a “natural” way (FlatBuffers option).
  • defaults_json (default True): Include default scalar values in emitted JSON.
  • size_prefixed (default False): Data buffers carry a 4-byte size prefix. This affects json_to_binary(), binary_to_json() and serialize_schema_bfbs() (the bfbs is size-prefixed too), so use the same Options when loading a bfbs back with from_bfbs().
  • output_enum_identifiers (default True): Output enum identifiers rather than numeric values.

ark_fbs.Schema

Schema wraps a flatbuffers::Parser instance plus a cached reflection schema used for buffer verification.

Constructors

  • Schema.from_fbs_file(schema_path: str, include_paths: list[str] = [], options: Options = Options(), root_type_override: str = "") -> Schema

    • schema_path: Path to the .fbs file.
    • 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_type in schema).
    • Raises: OSError (subclass) if the file cannot be read; SchemaError if parsing fails or root_type_override is unknown / not a table.
  • 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: SchemaError on 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: SchemaError if deserialization fails or root_type_override is unknown / not a table.

Methods

  • Schema.json_to_binary(json: str) -> bytes

    • Parses JSON using the loaded schema and returns the FlatBuffer binary.
    • Raises: JsonParseError if JSON parsing fails (including embedded NUL bytes); SchemaError if 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=False a 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_tables in that case.
    • Raises: VerifyError if the buffer fails verification or conversion fails; SchemaError if no root type is set; TypeError if data is not a contiguous byte buffer.
  • Schema.serialize_schema_bfbs() -> bytes

    • Returns the loaded schema serialized as .bfbs bytes (cached at construction).
    • Raises: SchemaError if the schema is not initialized.

Properties

  • Schema.root_type: str — name of the current root table, or "" if none.
  • Schema.file_identifier: str — the schema's file_identifier, or "" if none. When non-empty, binary_to_json() requires buffers to carry it.

Root type behavior

Schema.json_to_binary() and Schema.binary_to_json() require a root type. You must either:

  • Provide root_type in the schema (root_type A;), or
  • Pass root_type_override="A" when constructing the Schema.

The root type must be a table; a struct is rejected with SchemaError.

Thread safety

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.

Wheels / PyPI

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.

About

FlatBuffers schema parsing + JSON<->binary helpers (pybind11)

Resources

Stars

1 star

Watchers

0 watching

Forks

Releases

Packages

Contributors

Languages