Skip to content

resolve

resolve #

Resolve a captured-data file path against a target's declared schema.

The file API addresses a leaf (or a directory) by the chain of on-disk folder names from the target root — at each step a struct field, a Map key, or an Array index. These walkers turn such a chain into the CGType it names, raising [SchemaPathError][] the moment a component is not a real entry of the type at that position.

The server validates every request path with them, so an internet-exposed endpoint can only touch paths the schema actually declares — never a private, on-disk-but-off-schema file, and never a folder name a lenient key codec would otherwise alias. capturegraph-sync shares [is_storable_scalar][] when it walks a schema to enumerate its leaves.

SchemaPathError #

Bases: ValueError

A path component is not a declared entry of the schema at its position.

Source code in capturegraph-lib/capturegraph/types/schema/resolve.py
class SchemaPathError(ValueError):
    """A path component is not a declared entry of the schema at its position."""

is_container(cgtype) #

Whether cgtype is a composite directory type (Struct / Map / Array).

Source code in capturegraph-lib/capturegraph/types/schema/resolve.py
def is_container(cgtype: object) -> bool:
    """Whether ``cgtype`` is a composite directory type (Struct / Map / Array)."""
    return isinstance(cgtype, type) and issubclass(cgtype, (Struct, Map, Array))

is_schema_child(container, name) #

Whether name is a valid on-disk child entry of container.

A declared struct field's on-disk name, a canonical Map key, or a canonical Array index. Filters a directory listing down to what the schema declares, so an off-schema on-disk file (a stray module, a non-canonical folder) is never surfaced to a client.

Source code in capturegraph-lib/capturegraph/types/schema/resolve.py
def is_schema_child(container: type[CGType], name: str) -> bool:
    """Whether ``name`` is a valid on-disk child entry of ``container``.

    A declared struct field's on-disk name, a canonical Map key, or a canonical
    Array index. Filters a directory listing down to what the schema declares, so
    an off-schema on-disk file (a stray module, a non-canonical folder) is never
    surfaced to a client.
    """
    try:
        _descend(container, name)
    except SchemaPathError:
        return False
    return True

is_storable_scalar(cgtype) #

Whether cgtype is a storable leaf scalar, not a composite container.

Source code in capturegraph-lib/capturegraph/types/schema/resolve.py
def is_storable_scalar(cgtype: object) -> bool:
    """Whether ``cgtype`` is a storable leaf scalar, not a composite container."""
    return is_storable(cgtype) and not (
        isinstance(cgtype, type) and issubclass(cgtype, (Struct, Map, Array))
    )

resolve_schema_container(schema, components) #

The type addressed by components from schema (a directory position).

An empty path is schema itself (the target root). Every component must name a real entry of the type reached so far, else [SchemaPathError][].

Source code in capturegraph-lib/capturegraph/types/schema/resolve.py
def resolve_schema_container(
    schema: type[CGType],
    components: Sequence[str],
) -> type[CGType]:
    """The type addressed by ``components`` from ``schema`` (a directory position).

    An empty path is ``schema`` itself (the target root). Every component must
    name a real entry of the type reached so far, else [SchemaPathError][].
    """
    current: type[CGType] = schema
    for component in components:
        current = _descend(current, component)
    return current

resolve_schema_leaf(schema, components) #

The leaf scalar addressed by components from schema.

Walks the container chain over components[:-1] and resolves the final component; the result must be a scalar (a file leaf, carrying the extensions it accepts). Raises [SchemaPathError][] on any invalid component, or when the path stops short at a container rather than a leaf.

Source code in capturegraph-lib/capturegraph/types/schema/resolve.py
def resolve_schema_leaf(
    schema: type[CGType],
    components: Sequence[str],
) -> type[Scalar]:
    """The leaf scalar addressed by ``components`` from ``schema``.

    Walks the container chain over ``components[:-1]`` and resolves the final
    component; the result must be a scalar (a file leaf, carrying the
    ``extensions`` it accepts). Raises [SchemaPathError][] on any invalid
    component, or when the path stops short at a container rather than a leaf.
    """
    if not components:
        raise SchemaPathError("a leaf path needs at least one component")
    container = resolve_schema_container(schema, components[:-1])
    leaf = _descend(container, components[-1])
    if not (isinstance(leaf, type) and issubclass(leaf, Scalar)):
        raise SchemaPathError(
            f"{'/'.join(components)} is not a file leaf "
            f"(resolved to {getattr(leaf, '__name__', leaf)!r})"
        )
    return leaf