Skip to main content

Function-Styled Object Notation Lines — a line-based serialization format with typed schemas

Project description

FSONL

Function-Styled Object Notation Lines

A line-based serialization format where each record's type is immediately visible at the start of the line.

@schema rm(target: string, --force?: bool = false)
rm("tmp.log", force=true)
rm("/var/cache", force=false)
log("info", "server started")

Install

pip install fsonl

Quick Start

Parse with inline schema

import fsonl

text = """
@schema rm(target: string, --force?: bool = false)
rm("tmp.log")
rm("/var/cache", force=true)
"""

result = fsonl.loads(text)
for entry in result.entries:
    print(entry)
# {'type': 'rm', 'target': 'tmp.log', 'force': False}
# {'type': 'rm', 'target': '/var/cache', 'force': True}

Parse with code schema

import fsonl

schema = fsonl.Schema.from_string(
    "@schema log(level: string, msg: string)"
)

result = fsonl.loads('log("info", "started")\n', schema=schema)
print(result.entries[0])
# {'type': 'log', 'level': 'info', 'msg': 'started'}

Define schema from Python functions (3.10+)

import fsonl

schema = fsonl.Schema()

@schema.define
def rm(target: str, *, force: bool = False): ...

result = fsonl.loads('rm("tmp.log", force=true)\n', schema=schema)
print(result.entries[0])
# {'type': 'rm', 'target': 'tmp.log', 'force': True}

Serialize

import fsonl

schema = fsonl.Schema.from_string(
    "@schema log(level: string, msg: string)"
)

print(fsonl.dumps([{"type": "log", "level": "info", "msg": "hello"}], schema=schema))
# @schema log(level: string, msg: string)
# log("info", "hello")

Writer (append-friendly)

import fsonl

schema = fsonl.Schema.from_string("@schema event(level: string, msg: string)")

# First run: creates file with schema header + entries
with fsonl.Writer("events.fsonl", schema=schema) as w:
    w.write({"type": "event", "level": "info", "msg": "started"})

# Later: appends entries without duplicating the header
with fsonl.Writer("events.fsonl", schema=schema) as w:
    w.write({"type": "event", "level": "warn", "msg": "timeout"})

Stream from file

import fsonl

with open("events.fsonl", newline="") as f:
    for entry in fsonl.iter_entries(f):
        print(entry)

Raw mode (no schema binding)

import fsonl

result = fsonl.loads_raw('x(1, "hello", flag=true)\n')
entry = result[0]
print(entry["type"])        # 'x'
print(entry["positional"])  # [1, 'hello']
print(entry["named"])       # {'flag': True}

API

Parsing

Function Description
loads(text, *, schema, ignore_inline_schema, extra_fields) Parse FSONL text with schema binding
load(fp, **kwargs) Parse from file object with schema binding
loads_raw(text) Parse FSONL text without binding (Stage 1 only)
load_raw(fp) Parse from file object without binding (Stage 1 only)
iter_entries(source, *, schema, ignore_inline_schema, extra_fields) Lazy iterator over bound entries
iter_raw(source) Lazy iterator over raw entries
bind(entry, schema, *, line, extra_fields) Bind a single raw dict to a Schema

Serialization

Function Description
dumps(entries, *, schema, allow_extra, exclude_schema) Serialize to FSONL text
dump(entries, fp, *, schema, allow_extra, exclude_schema) Serialize to file object
Writer(path, *, schema) Append-friendly file writer (auto header management)

Schema

Method Description
Schema.from_string(text) Create from @schema lines
Schema.from_fsonl(text) Extract @schema from FSONL text (non-schema lines ignored)
Schema.from_file(path) Load @schema from a .fsonl file
@schema.define Decorator: define schema from function signature (Python 3.10+)
schema.add(text) Add more @schema definitions
schema.get(type_name) Look up a type definition
schema.has(type_name) Check if a type is defined
schema.type_names() List all defined type names

Options

Option Default Description
ignore_inline_schema False Skip @schema directives in the content
allow_extra False (dumps only) Ignore extra keys not in schema
exclude_schema False (dumps only) Omit @schema lines from output
extra_fields ExtraFieldPolicy.ERROR Policy for undeclared named arguments

Errors

All errors include line numbers: str(error) produces "line 42: message".

Exception Kind Stage
ParseError syntax_error Stage 1 (syntax parse)
SchemaError schema_error Schema definition / cross-validation
BindError bind_error Stage 2 (data vs schema mismatch)

All inherit from FsonlError, which inherits from Exception.

Schema Types

string          -- JSON string
number          -- JSON number (int or float)
bool            -- true / false
null            -- null
any             -- any JSON value
string[]        -- array of strings
(string | number)[]  -- array of union
{ cmd: string, id?: number }  -- fixed-shape object
string | null   -- nullable string

CLI

# Parse with schema binding (default)
echo '@schema x(a: number)\nx(1)' | python -m fsonl parse

# Raw parse (no binding)
echo 'x(1)' | python -m fsonl parse --raw

# Extract @schema directives only
echo '@schema x(a: number)\nx(1)' | python -m fsonl parse --schema

Format Overview

  • One entry per line: type(args)
  • Values are JSON literals: strings, numbers, booleans, null, arrays, objects
  • Positional args come before named args: log("info", tag="v2")
  • Comments: // ... (outside argument lists only)
  • File extension: .fsonl, MIME: text/fsonl, encoding: UTF-8

Specification

License

MIT

Project details


Download files

Download the file for your platform. If you're not sure which to choose, learn more about installing packages.

Source Distribution

fsonl-0.4.0.tar.gz (35.5 kB view details)

Uploaded Source

Built Distribution

If you're not sure about the file name format, learn more about wheel file names.

fsonl-0.4.0-py3-none-any.whl (25.7 kB view details)

Uploaded Python 3

File details

Details for the file fsonl-0.4.0.tar.gz.

File metadata

  • Download URL: fsonl-0.4.0.tar.gz
  • Upload date:
  • Size: 35.5 kB
  • Tags: Source
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fsonl-0.4.0.tar.gz
Algorithm Hash digest
SHA256 62a61150719c9e6756a3aeee16849ed9032aca99654b0c372c8195305aa93429
MD5 680e636c6cb52b80a6b9818c2aa1cd03
BLAKE2b-256 a0beb035d27aa1bee0eb3ee0e093dbf2e640633367c6a8dc450162e3f934be72

See more details on using hashes here.

Provenance

The following attestation bundles were made for fsonl-0.4.0.tar.gz:

Publisher: publish.yml on fsonl/fsonl-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

File details

Details for the file fsonl-0.4.0-py3-none-any.whl.

File metadata

  • Download URL: fsonl-0.4.0-py3-none-any.whl
  • Upload date:
  • Size: 25.7 kB
  • Tags: Python 3
  • Uploaded using Trusted Publishing? Yes
  • Uploaded via: twine/6.1.0 CPython/3.13.7

File hashes

Hashes for fsonl-0.4.0-py3-none-any.whl
Algorithm Hash digest
SHA256 7633f25494e50b16f092f3ca3e3b7991bc56eb7301d1c5aa4d90bb7a01d58b6a
MD5 1cc3c4136a3f71271d60c481f46e3802
BLAKE2b-256 e3ee2d1d8ae92e450139946a1a30c845af6db5a3fef924ca86921fccc1cb783b

See more details on using hashes here.

Provenance

The following attestation bundles were made for fsonl-0.4.0-py3-none-any.whl:

Publisher: publish.yml on fsonl/fsonl-py

Attestations: Values shown here reflect the state when the release was signed and may no longer be current.

Supported by

AWS Cloud computing and Security Sponsor Datadog Monitoring Depot Continuous Integration Fastly CDN Google Download Analytics Pingdom Monitoring Sentry Error logging StatusPage Status page