popoto.transfer.format¶
popoto.transfer.format
¶
JSON Lines export format for :mod:popoto.transfer.
The on-disk format is a single manifest object on the first line followed by one JSON object per exported record::
{"popoto_export": 1, "model": "Memory", "exported_at": "...", ...}
{"key": "Memory:abc", "values": {...}, "state": {...}, "model_state": {...}}
{"key": "Memory:def", "values": {...}, "state": {}, "model_state": {}}
Only the standard library is used. Values that JSON cannot represent natively
are coerced through Popoto's existing per-type encoder registry
(:data:popoto.models.encoding.TYPE_ENCODER_DECODERS), whose encoders already
emit JSON-primitive tagged dicts such as
{"__Decimal__": True, "as_encodable": "1.23"}. The inverse uses
:data:popoto.models.encoding.DECODERS_BY_KEYSTRING.
Two tags are local to this module because the shared registry has no entry for them:
__bytes__
Binary payloads (e.g. a serialized embedding vector) carried as base64.
__dictpairs__
A mapping with non-string keys, which JSON objects cannot express.
FORMAT_VERSION = 1
module-attribute
¶
Version of the popoto_export JSON Lines format written by this module.
Bumped whenever the record or manifest shape changes incompatibly. Import refuses a file whose version it does not recognise; cross-version compatibility is explicitly not promised.
MANIFEST_KEY = 'popoto_export'
module-attribute
¶
Manifest field carrying :data:FORMAT_VERSION; also the manifest marker.
popoto_version()
¶
Return the installed popoto version, or a sentinel when unknown.
to_jsonable(value)
¶
Coerce value into something :func:json.dumps accepts.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
Any
|
Any Python value taken from a model field or from a field's
|
required |
Returns:
| Type | Description |
|---|---|
Any
|
A JSON-representable structure. Non-primitive types are wrapped in a |
Any
|
tagged dict that :func: |
Raises:
| Type | Description |
|---|---|
TypeError
|
If the value has no encoder and is not a JSON primitive or container. Raising here is deliberate: silently stringifying an unknown type would produce an export that imports to the wrong value with no diagnostic. |
Source code in src/popoto/transfer/format.py
from_jsonable(value)
¶
Reverse :func:to_jsonable.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
value
|
Any
|
A structure parsed from a JSON Lines record. |
required |
Returns:
| Type | Description |
|---|---|
Any
|
The original Python value, with tagged dicts restored to their types. |
Source code in src/popoto/transfer/format.py
build_manifest(model_name, filter_repr, filter_kwargs, matched_count, fields, mixins, embedding_provenance)
¶
Assemble the manifest object written as the export's first line.
filter and matched_count are deliberately separate members: a
filter that matched nothing is {"filter": "Q(x='y')", "matched_count":
0} while an empty model is {"filter": null, "matched_count": 0}.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
model_name
|
str
|
|
required |
filter_repr
|
'str | None'
|
Rendered provenance of the applied filter, or |
required |
filter_kwargs
|
dict
|
The plain keyword filters, JSON-coerced. |
required |
matched_count
|
int
|
Number of keys the filter resolved to, recorded at resolution time (export is not a point-in-time snapshot). |
required |
fields
|
dict
|
Per-field |
required |
mixins
|
dict
|
Per-model-level-mixin |
required |
embedding_provenance
|
dict
|
Per-field |
required |
Returns:
| Type | Description |
|---|---|
dict
|
A JSON-serializable manifest dict. |
Source code in src/popoto/transfer/format.py
dump_line(obj)
¶
Serialize one manifest or record object as a newline-terminated line.
iter_lines(stream)
¶
Yield (line_number, raw_line) for every non-blank line.
Line numbers are 1-based and count blank lines, so a reported number matches what an operator sees in an editor.
Source code in src/popoto/transfer/format.py
parse_line(raw)
¶
Parse one JSON Lines line into a dict.
Raises:
| Type | Description |
|---|---|
ValueError
|
If the line is not valid JSON or is not a JSON object.
The caller counts this as an |