API reference
Every call and argument this package exposes, pulled directly from the
source's own docstrings — so a person or an AI agent doesn't have to go
read structile's Python source to know what open() accepts. This page
is generated (via mkdocstrings) from
whatever's actually installed, so it can't drift from the real signatures
the way a hand-written reference could.
This covers the everyday surface — open()/diff(), format/interpreter
selection, viewer settings, and what a call hands back. It doesn't list
every public name: deeper plugin-authoring internals like load_plugins
and PluginRecord, and the raw StructileWidget/StructileDiffWidget
classes behind the widget renderer, are covered in
Writing and distributing interpreters instead, in
context, rather than repeated here as bare signatures.
Rendering a value
structile.open
open(
obj: Any,
*,
name: Optional[str] = None,
height: int = 600,
config: Optional[Union[Options, Dict[str, Any]]] = None,
interpreter: Optional[InterpreterSpec] = None,
format: Optional[str] = None,
path: Optional[Union[str, Path]] = None,
renderer: Optional[str] = None,
out: Optional[Union[str, Path]] = None,
auto_open: bool = True,
default: Optional[Callable[[Any], Any]] = None,
**settings: Any,
) -> RenderHandle
Display a Python value through the active renderer. Always returns a
RenderHandle (never None) with .path, .value, .open(),
.to_html(), .save(path), and a one-line repr() — evaluate it as
the last expression in a Jupyter cell, or pass it to
IPython.display.display, and it renders itself richly there too.
See https://danieltuzes.github.io/structile/python-library/ for
examples and the full picture — this is a parameter reference, not a
tutorial. Shadows
the open builtin — always call this namespace-qualified
(structile.open(...)), never from structile import open.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
obj
|
Any
|
the value to display — any mix of dict/list/tuple/set/None/bool/
int (any size)/float/str/numpy scalar — or a |
required |
name
|
Optional[str]
|
display name. Defaults to the loaded file's stem, else "data". |
None
|
height
|
int
|
iframe height in px ( |
600
|
config
|
Optional[Union[Options, Dict[str, Any]]]
|
viewer settings for this call — an |
None
|
**settings
|
Any
|
individual viewer settings for this call — the numeric
layout knobs ( |
{}
|
interpreter
|
Optional[InterpreterSpec]
|
a path to a |
None
|
format
|
Optional[str]
|
|
None
|
path
|
Optional[Union[str, Path]]
|
save destination, overriding |
None
|
renderer
|
Optional[str]
|
|
None
|
out
|
Optional[Union[str, Path]]
|
also write the standalone HTML snapshot here (any renderer). |
None
|
auto_open
|
bool
|
set |
True
|
default
|
Optional[Callable[[Any], Any]]
|
called on any value that isn't one of |
None
|
structile.diff
diff(
left: Any,
right: Any,
*,
interpreter: Optional[
Union[
InterpreterSpec,
Tuple[
Optional[InterpreterSpec],
Optional[InterpreterSpec],
],
]
] = None,
format: Optional[
Union[str, Tuple[Optional[str], Optional[str]]]
] = None,
name: Optional[
Tuple[Optional[str], Optional[str]]
] = None,
view: str = "unified",
key_columns: Optional[list] = None,
height: int = 600,
renderer: Optional[str] = None,
out: Optional[Union[str, Path]] = None,
auto_open: bool = True,
default: Optional[
Union[
Callable[[Any], Any],
Tuple[
Optional[Callable[[Any], Any]],
Optional[Callable[[Any], Any]],
],
]
] = None,
) -> DiffRenderHandle
Display a two-sided diff of left vs right through the active
renderer. Always returns a DiffRenderHandle with .path,
.left_payload/.right_payload, .left_value/.right_value,
.open(), .to_html(), .save(path).
See https://danieltuzes.github.io/structile/python-library/#comparing-two-files-structilediff
for examples. Deliberately narrower than open(): no per-side viewer
config=/**settings, and the diff graph itself is always read-only
for every renderer (including widget) — only each side's own source
pane can be independently edited/saved (see .left_value/
.right_value, which read through to the live StructileDiffWidget
for the widget renderer, same as RenderHandle.value does for
open()).
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
left
|
Any
|
each independently accepts anything |
required |
right
|
Any
|
same contract as |
required |
interpreter
|
Optional[Union[InterpreterSpec, Tuple[Optional[InterpreterSpec], Optional[InterpreterSpec]]]]
|
a single value applies to BOTH sides (the common
case: two files in the same format/schema); a |
None
|
format
|
Optional[Union[str, Tuple[Optional[str], Optional[str]]]]
|
same single-value-or- |
None
|
name
|
Optional[Tuple[Optional[str], Optional[str]]]
|
|
None
|
view
|
str
|
|
'unified'
|
key_columns
|
Optional[list]
|
table key-column overrides — same shape the standalone viewer's own diff header accepts. |
None
|
height
|
int
|
iframe height in px ( |
600
|
renderer
|
Optional[str]
|
same as |
None
|
out
|
Optional[Union[str, Path]]
|
same as |
None
|
auto_open
|
bool
|
same as |
True
|
default
|
Optional[Union[Callable[[Any], Any], Tuple[Optional[Callable[[Any], Any]], Optional[Callable[[Any], Any]]]]]
|
same escape hatch as |
None
|
Converting between formats
convert
convert(
src: Union[str, Path],
dst_format: str,
interpreter: Optional[InterpreterSpec] = None,
) -> str
Convert data from one of the viewer's formats to another, entirely
outside the widget/notebook — parse src, then serialize the result as
dst_format, returning the converted text. See
https://danieltuzes.github.io/structile/python-library/#converting-between-formats
for the built-in-vs-JS-runtime boundary and examples.
Parameters:
| Name | Type | Description | Default |
|---|---|---|---|
src
|
Union[str, Path]
|
a path (format inferred from its extension: .json/.py/.csv/.tsv/
.xml/.html —
or, once an interpreter is attached to it, any other extension too,
e.g. .ini) or a literal string of source text (sniffed: JSON, else
Python-repr, else XML if it looks like markup — there's no
|
required |
dst_format
|
str
|
|
required |
interpreter
|
Optional[InterpreterSpec]
|
a path to a |
None
|
Custom formats
structile.register_interpreter
Register one or more interpreters for a file extension, once, at
import time — so later structile.open(path) / convert(path, ...) calls
don't need interpreter= at all:
structile.register_interpreter(".xml", "interpreters/generic_xml.js")
structile.register_interpreter(".html", ["interpreters/html.js", "interpreters/generic_xml.js"])
interpreter is a single path/raw JS source/InterpreterSource, or a
list/tuple of candidates tried in order — the first one that
successfully parses the data wins (see select_interpreter). None
unregisters ext (same as unregister_interpreter).
A direct call here always wins over a plugin's own registration for the
same ext (see _plugins.py's precedence rule) — calling this
"forgets" any plugin ownership of ext recorded so far, so a later
load_plugins(force=True) can't silently re-overwrite what was just set
directly.
structile.unregister_interpreter
Remove any interpreter(s) registered for ext.
structile.get_registered_interpreter
The raw spec registered for ext — a single candidate, a list, or
None if nothing's registered. See resolve_candidates for the
normalized list form callers actually use.
Triggers entry-point plugin discovery first (lazy, at most once per
process — see _plugins.load_plugins): every renderer's resolution
path (open()/diff()'s markup-mode detection, resolve_candidates's
own registry fallback below, convert()'s format inference) reaches the
registry through this one function, so a plugin's registration becomes
visible here with no import of the plugin package and no explicit
registration call needed.
Custom/branded distributions
The calls behind building a custom/branded distribution — baking a curated set of interpreters into your own copy of the viewer, registering that same manifest with the Python-side registry, and pointing every renderer at the result. See that guide for the end-to-end walkthrough and a downloadable template; these are the exact signatures.
structile.build_custom_html
build_custom_html(
manifest: ManifestSource,
*,
source_html: Optional[Union[str, Path]] = None,
output: Optional[Union[str, Path]] = None,
) -> str
Bake manifest's {extensions, path, name, format} entries into a
copy of structile.html, and return the resulting HTML text.
manifest holds ANY NUMBER of interpreters, and baking several formats
into one branded viewer is the normal case. Two accepted shapes (see
structile.manifest.load_manifest): a path to a JSON file shaped
{"interpreters": [ ... ]}, whose path values resolve relative to
that file; or, in memory, the inner list of entry dicts on its own —
NOT the wrapping object. Each entry names its own extensions (one or
several) and format, and one build freely mixes the two contracts
("xml"/"html" use interpretXML/serializeXML, every other
format string uses interpretText/serializeText). If two entries
claim the same extension the later one silently wins — no error — so
keep the list unambiguous. Extensions absent from the manifest behave
exactly as in the stock viewer, and the built-in JSON/Python-repr/CSV
formats need no entry at all.
source_html: the base HTML to bake into — defaults to
find_viewer_html()'s own resolution (the dev source next to this
repo, or the bundled production build). Pass an explicit path to
bake into a specific build instead (e.g. an already-minified
structile.prod.html).
output: if given, the resulting HTML is also written there.
structile.register_interpreters_from_manifest
Call register_interpreter() once per entry in manifest (see
structile.manifest.load_manifest for accepted shapes) — the
Python-side counterpart to structile.custom_html.build_custom_html,
so a custom distribution can drive both the standalone-HTML baking and
the Python registry from the exact same manifest instead of
maintaining two separate lists.
A plugin's own register(registry) callback can't call this directly
— the facade it receives only exposes register_interpreter() (see
_plugins.py's _RegistryFacade) — so loop over
structile.manifest.load_manifest(...) and call
registry.register_interpreter(ext, InterpreterSource(text, name=...))
per entry there instead; see README.md's "Building a custom/branded
distribution" section for a worked example.
structile.set_viewer_html
Point every structile renderer (open(), diff(), the widget/
browser/file renderers, .to_html()) at a specific viewer HTML
file — None reverts to find_viewer_html()'s normal resolution.
This is the documented way for a thin wrapper package to ship its own
customized structile.html (e.g. one built with interpreters baked in
via structile.build_custom_html) without forking structile itself:
call this once, from the wrapper package's own __init__.py, with the
path to its bundled HTML. It's a thin wrapper around the
STRUCTILE_VIEWER_HTML env var (read fresh by find_viewer_html() on
every call, never cached), just under a name that documents this as a
supported integration point rather than only a dev/testing knob.
structile.load_manifest
Normalize source into a list of InterpreterManifestEntry.
source is either:
- a path to a JSON manifest file — {"interpreters": [...]}, each item
shaped like InterpreterManifestEntry's fields, with path values
resolved relative to the manifest file's own directory; or
- a plain list of dicts (that same shape) or InterpreterManifestEntry
instances directly — path values are used as-is, since there's no
manifest file to resolve a relative path against.
structile.plugins
Every structile.interpreters entry point discovered so far —
loaded successfully or not (check .success/.error): entry-point
name, distribution name/version, and which extensions it registered —
a support/debugging surface a user can run themselves to answer "why
did my file open with the wrong schema?" or "why didn't my plugin load
at all?" without reading any source or turning on logging. Including
failures here (rather than only ones that loaded) matters precisely
because the person most likely to call this is the one whose plugin
isn't working — for them, an empty/incomplete list is indistinguishable
from "never installed". Triggers discovery itself (same lazy/idempotent
rule as everywhere else), so it's safe to call before anything else has
resolved an interpreter.
Viewer settings
structile.Options
structile.set_option
Set a module-level default option.
structile.set_option("theme", "dark")
Equivalent to structile.options.<name> = value. Pass value=None to
unset it again (falls back to the viewer's built-in default).
structile.get_option
Read a module-level default option (None if unset).
structile.reset_option
Unset a module-level default option (falls back to the viewer default).
structile.use
Set the module-level default renderer, matplotlib.use()-style.
structile.use("browser")
Equivalent to set_option("renderer", renderer) / options.renderer =
renderer. See structile.render.RENDERERS for the valid names.
What a call returns
structile.RenderHandle
Bases: _RenderHandleBase
What every open() call returns, regardless of renderer.
.value is the displayed value (JSON-safe data, or raw XML text
when an interpreter= was used) — for the widget renderer this stays
live, updated on every Save (same as StructileWidget.value always
was); for every other renderer it's a static snapshot of what was
rendered, since there's no channel back from a plain browser tab/file to
Python. .widget is the underlying StructileWidget for the widget
renderer, None otherwise — an escape hatch for anywidget-specific
features (.dirty, .dirty_count, .on_msg, ...) this handle doesn't
itself proxy.
structile.DiffRenderHandle
Bases: _RenderHandleBase
Returned by structile.diff() — the two-sided counterpart to
RenderHandle, deliberately narrow: the diff GRAPH is always read-only
(there's no single .value the way a plain document has one — see
.left_payload/.right_payload for the static snapshot each side
started from), but for the widget renderer, .left_value/
.right_value read through to the live StructileDiffWidget the same
way RenderHandle.value reads through to StructileWidget — each
side's own source pane is independently editable/saveable in embedded
diff mode (structile.html's performDiffSideSave), even though
the graph itself never is.