Storage is “where content is stored” — distinct from
tai42_contract.template (“what we do with it”, the render mixins). The store
exposes the text surface load / list / upload / delete /
delete_dir plus the binary/media surface load_bytes / upload_bytes /
stat, with the module-level assert_not_root guarding deletes against the
store root. The binary methods ship text-bridging defaults so a text-only backend
satisfies the whole contract with no new code; binary-native backends override.
ObjectStat
tai42_contract.storage.ObjectStat
Storage.stat.
Carries only content_type — the MIME type consumed here for image/audio
media gating (a backend that stores no metadata infers it from the path, a
metadata-bearing backend returns the stored type). Frozen: a stat snapshot is
a value, not a mutable handle.
Attributes
Storage
tai42_contract.storage.Storage
Members
load
tai42_contract.storage.Storage.load
path.
Must raise FileNotFoundError when the item does not exist — the
manager relies on that exact type to map a missing {% include %} /
{% extends %} dependency to Jinja’s TemplateNotFound (so
{% include ... ignore missing %} works). Any other failure (auth,
network) must propagate as its own error.
Parameters
list
tai42_contract.storage.Storage.list
upload
tai42_contract.storage.Storage.upload
delete
tai42_contract.storage.Storage.delete
delete_dir
tai42_contract.storage.Storage.delete_dir
load_bytes
tai42_contract.storage.Storage.load_bytes
path, with the same FileNotFoundError
contract as load.
Text-bridge default: reads the text via load and UTF-8 encodes it,
so a text-only backend serves bytes for free. A binary-native backend
(e.g. S3) overrides to return the stored bytes unaltered.
Parameters
upload_bytes
tai42_contract.storage.Storage.upload_bytes
data at path, optionally tagging content_type.
Text-bridge default: STRICT-decodes data as UTF-8 and stores it via
upload; content_type is ignored (a text backend keeps no MIME
metadata). The decode never passes errors= — non-UTF-8 bytes raise
UnicodeDecodeError loudly rather than corrupting the stored content. A
binary-native backend overrides to store data and content_type as-is.
Parameters
stat
tai42_contract.storage.Storage.stat
path.
Path-inference default: guesses content_type from the path suffix via
mimetypes.guess_type — it does NOT verify existence (it answers from
the path string), so a standalone stat on a metadata-less backend is
best-effort metadata; existence for a real read is enforced by the paired
load_bytes. A metadata-bearing backend (e.g. S3) overrides to
return the stored content-type and maps a missing object to
FileNotFoundError.
Parameters
assert_not_root
tai42_contract.storage.assert_not_root
"", ".",
"/", " "), or one whose normalized form escapes to or above the
root ("a/..", "./x/../..") would target every stored item, so
deleting it is refused. Shared by all storage backends to keep the guard
identical.
Parameters

