httk.core.storage

Storage declarations, identity, and stored-property protocols.

Submodules

Attributes

STORAGE_INFO_ATTRIBUTE

Class attribute name where a storable class may attach its StorageInfo.

DedupPolicy

How a storage layer deduplicates saved instances of a class.

STORED_PROPERTY_PROJECTIONS_ATTRIBUTE

Exact-class attribute holding a backing's property-projection mapping.

StoredPropertyQuery

Build one predicate from a context, protocol operator, and parsed literal.

StoredPropertyResponse

Extract one served property value from one concrete backing record.

StoredPropertySort

Select one sortable backing value from a query context.

Exceptions

StorageProjectionCycleError

Raise when a projected record graph contains an active cycle.

QueryLiteralError

A query literal cannot represent the property value requested.

Classes

IdentitySkip

Field marker: exclude the field from content identity.

Indexed

Field marker: request a single-column index on this field's column(s).

Related

Field marker: relationship metadata for a reference or list-of-storable field.

Shape

Field marker: fixed or variable shape for a vector-valued field.

Skip

Field marker: the field exists on the dataclass but is not stored.

StorageInfo

Optional class-level storage declaration for a storable dataclass.

Unique

Field marker: request a unique index on this field's column(s).

WeakLink

Class-level declaration of a store-managed, lineage-level link to another storable class.

stored_property

A derived property that a storage layer stores and makes queryable.

QueryContext

Factory and algebra used by domain-owned property query callbacks.

QueryExpression

One backend-neutral boolean predicate.

QueryField

A durable field selected from a QueryScope.

QueryScope

A record or correlated child/reference scope.

QueryValue

A scalar or aggregate value participating in a query expression.

StoredPropertyProjection

One domain-owned projection of a served property for one backing.

Functions

canonical_form(obj, *[, as_record, projector, extras])

Return the versioned, type-tagged canonical JSON for a record value.

content_id(obj, *[, as_record, projector, extras])

Return the lowercase SHA-256 content identity of obj.

project_storage_record(record_type, source)

Project and validate one record level, returning field values by name.

register_canonical_encoder(python_type, encoder)

Register one deterministic encoder for an exact custom Python type.

resolve_storage_record(source, *[, as_record])

Resolve the exact record target for source without constructing it.

storage_identity_name(record_type)

Return the logical identity name, independent of physical storage naming.

stored_property_projections(cls)

Return a validated property's projection map declared on cls.

Package Contents

exception httk.core.storage.StorageProjectionCycleError(path, record_type)[source]

Bases: ValueError

Raise when a projected record graph contains an active cycle.

Parameters:
  • path (str) – The canonical field path where the cycle was detected.

  • record_type (type[Any]) – The record class being projected when the cycle was found.

path
record_type
httk.core.storage.canonical_form(obj, *, as_record=None, projector=project_storage_record, extras=None)[source]

Return the versioned, type-tagged canonical JSON for a record value.

Storage integrations may supply a caching projector to reuse the exact per-record mappings traversed while computing identity.

Record fields marked with IdentitySkip, or represented by stored_property, are outside the content identity. Registered custom encoders apply only to exact leaf types.

extras fold additional save-time key/value pairs into the identity of the root record only; child records never receive them. When extras is None or empty the output is byte-identical to omitting it.

Parameters:
Returns:

Versioned, type-tagged canonical JSON.

Raises:
  • TypeError – If a value or projection cannot be represented.

  • ValueError – If a projection is invalid or contains a cycle.

Return type:

str

httk.core.storage.content_id(obj, *, as_record=None, projector=project_storage_record, extras=None)[source]

Return the lowercase SHA-256 content identity of obj.

The digest covers canonical_form(), including exact-type leaf encodings and excluding fields marked with IdentitySkip.

extras fold additional save-time key/value pairs into the root record’s identity (see canonical_form()). Extras-bearing calls bypass the trusted per-instance cache entirely, so they never read or poison it.

Parameters:
Returns:

The lowercase SHA-256 hexadecimal digest.

Raises:
  • TypeError – If a value or projection cannot be represented.

  • ValueError – If a projection is invalid or contains a cycle.

Return type:

str

httk.core.storage.project_storage_record(record_type, source)[source]

Project and validate one record level, returning field values by name.

Projection classes may declare a source class and classmethod projection; otherwise source must already be an instance of record_type. A projection used by the trusted content-id path must be deterministic for the immutable lifetime of its source: the content-id cache is governed by that immutability contract.

Parameters:
  • record_type (type[Any]) – The frozen dataclass record class to project.

  • source (Any) – A record instance or declared projection source.

Returns:

Field values present at this record level.

Raises:
  • TypeError – If the record or projection declaration is invalid.

  • ValueError – If a projection omits a required field or names an unknown one.

Return type:

collections.abc.Mapping[str, object]

httk.core.storage.register_canonical_encoder(python_type, encoder)[source]

Register one deterministic encoder for an exact custom Python type.

Leaf values use exact-type lookup, so a registered encoder for a base class does not apply to subclasses. The encoder must return JSON-compatible data.

Parameters:
  • python_type (type[Any]) – The exact custom class to encode.

  • encoder (collections.abc.Callable[[Any], Any]) – The deterministic encoder callable.

Raises:
  • TypeError – If the type or encoder is invalid.

  • ValueError – If an encoder is already registered for the class.

httk.core.storage.resolve_storage_record(source, *, as_record=None)[source]

Resolve the exact record target for source without constructing it.

Parameters:
  • source (Any) – The source value whose storage record target is requested.

  • as_record (type[Any] | None) – An explicit record class override, if supplied.

Returns:

The validated frozen dataclass record class.

Raises:

TypeError – If the resolved target is not a frozen dataclass.

Return type:

type[Any]

httk.core.storage.storage_identity_name(record_type)[source]

Return the logical identity name, independent of physical storage naming.

Parameters:

record_type (type[Any]) – The record class whose logical identity name is requested.

Returns:

The declared identity name or the fully qualified class name.

Raises:

TypeError – If record_type is not a class or has an invalid storage declaration.

Return type:

str

httk.core.storage.STORAGE_INFO_ATTRIBUTE: Final = '__httk_storage__'[source]

Class attribute name where a storable class may attach its StorageInfo.

type httk.core.storage.DedupPolicy = Literal['content_id', 'by_value', 'none'][source]

How a storage layer deduplicates saved instances of a class.

  • "content_id": reuse an existing row whose stored content identity matches (the default; suited to immutable value objects).

  • "by_value": reuse an existing row whose stored columns all match (suited to join-objects such as tags and references, whose identity is their value).

  • "none": always insert a new row.

Values equal across int and Fraction can hash differently, while Decimal and Fraction unify; naive and aware datetimes are distinct. Records combining those sources may therefore not deduplicate.

class httk.core.storage.IdentitySkip[source]

Field marker: exclude the field from content identity.

class httk.core.storage.Indexed[source]

Field marker: request a single-column index on this field’s column(s).

class httk.core.storage.Related[source]

Field marker: relationship metadata for a reference or list-of-storable field.

Applies to a field holding another storable class (a reference field) or a list/tuple of storable classes. When the field’s target class is served alongside the declaring class, the storage layer surfaces the field as a relationship; this marker attaches the OPTIMADE per-identifier metadata that flows into each emitted RelatedEntryrole (machine readable, OPTIMADE v1.3 meta.role) and description (human readable, OPTIMADE v1.2 meta.description). serve=False suppresses the field as a relationship entirely.

Parameters:
  • role – The machine-readable relationship role, if any.

  • description – The human-readable relationship description, if any.

  • serve – Whether the field is served as a relationship at all.

role: str | None = None
description: str | None = None
serve: bool = True
class httk.core.storage.Shape[source]

Field marker: fixed or variable shape for a vector-valued field.

rows >= 1 declares a fixed-shape value stored inline (flattened row-major into columns). rows == 0 declares a variable number of rows with cols fixed columns each, stored out-of-line (one row per entry, in insertion order).

Parameters:
  • rows – Number of rows; 0 means variable-length.

  • cols – Number of columns per row; must be at least 1.

Raises:

ValueError – If rows is negative or cols is less than 1.

rows: int
cols: int = 1
class httk.core.storage.Skip[source]

Field marker: the field exists on the dataclass but is not stored.

class httk.core.storage.StorageInfo[source]

Optional class-level storage declaration for a storable dataclass.

Attach as the class attribute named by STORAGE_INFO_ATTRIBUTE (__httk_storage__), annotated ClassVar[StorageInfo] so dataclass processing ignores it. A storage layer may also accept an instance as an external override for classes that cannot be modified.

Parameters:
  • storage_name – The physical storage name; None derives one from the class name. Relational backends use it as the table name, and document stores use it as the collection name.

  • indexes – Composite indexes, each a tuple of field names.

  • dedup – The deduplication policy applied when saving; see DedupPolicy.

  • links – Class-level weak-link declarations; see WeakLink.

  • identity_name – The logical name included in content identity; None derives it from the declaring class and its bases.

Raises:

ValueError – If dedup or an identity name or index declaration is invalid.

storage_name: str | None = None
indexes: tuple[tuple[str, Ellipsis], Ellipsis] = ()
dedup: DedupPolicy = 'content_id'
identity_name: str | None = None
class httk.core.storage.Unique[source]

Field marker: request a unique index on this field’s column(s).

Class-level declaration of a store-managed, lineage-level link to another storable class.

Declared in StorageInfo.links on the source class (links are directed). A weak link is a store-managed association living in a dedicated link table, not in any record field: it binds lineages, associating this record’s logical id with a target record’s logical id, and both endpoints always resolve to the latest revision on their respective side (this is what makes the link weak, in contrast to sid-pinned reference and child fields). Link rows are themselves append-only lineages — they are revisable, retractable, and as_of-aware — and are set-valued: a source lineage may link many targets under the same declaration. Because links are not part of a record’s value, they do not participate in content identity; adding or retracting a link never changes the record’s content_id.

Only links declared exposed_relationship=True are served through the OPTIMADE relationship facility; role and description carry the same per-identifier OPTIMADE metadata as Related into each served relationship. target is the storable frozen dataclass this link points at; only that it is a class is checked here, as deep storability validation is performed by the storage layer.

Parameters:
  • name – The link name; must be a valid Python identifier. Namespaces the link (e.g. accessed as record.links.<name>).

  • target – The storable class this link points at.

  • exposed_relationship – Whether the link is served through the OPTIMADE relationship facility.

  • role – The machine-readable relationship role, if any.

  • description – The human-readable relationship description, if any.

Raises:
  • ValueError – If name is not a valid Python identifier.

  • TypeError – If target is not a class.

name: str
target: type
exposed_relationship: bool = False
role: str | None = None
description: str | None = None
class httk.core.storage.stored_property(fget=None, fset=None, fdel=None, doc=None)[source]

Bases: property

A derived property that a storage layer stores and makes queryable.

Use exactly like property (getter only). The value type is read from the getter’s return annotation. On save, the storage layer evaluates and stores the value alongside the declared fields; on load, the value is recomputed by the property rather than passed to __init__. The getter must declare a return annotation when the property is created.

Parameters:
  • fget (collections.abc.Callable[Ellipsis, Any] | None) – The getter function whose derived value is stored.

  • fset (collections.abc.Callable[Ellipsis, Any] | None) – An optional setter, normally unused by storage declarations.

  • fdel (collections.abc.Callable[Ellipsis, Any] | None) – An optional deleter, normally unused by storage declarations.

  • doc (str | None) – An optional property documentation string.

Raises:

TypeError – If fget has no return annotation.

httk.core.storage.STORED_PROPERTY_PROJECTIONS_ATTRIBUTE: Final = '__httk_stored_properties__'[source]

Exact-class attribute holding a backing’s property-projection mapping.

class httk.core.storage.QueryContext[source]

Bases: QueryScope, Protocol

Factory and algebra used by domain-owned property query callbacks.

field and scope start at the backing record. scope can be called again on a child/reference scope, so callbacks can express correlated nested predicates without seeing storage tables or joins. exact_equal requests equality in the property’s exact stored domain; it is the operation to use for fractions and other values for which a presentation float would be lossy.

constant(value)[source]

Return a query value for an already validated literal constant.

Parameters:

value (object) – The validated literal to place in the query.

Returns:

A query value for the literal.

Return type:

QueryValue

null()[source]

Return the explicit null query value.

Returns:

A query value representing null.

Return type:

QueryValue

always_true()[source]

Return the predicate which matches every backing record.

Returns:

A predicate that always matches.

Return type:

QueryExpression

always_false()[source]

Return the predicate which matches no backing record.

Returns:

A predicate that never matches.

Return type:

QueryExpression

compare(left, operator, right)[source]

Compare values with a backend-supported comparison operator.

Domain callbacks normally use equal(), exact_equal(), or explicit operator dispatch for a protocol’s filter grammar. The operator is deliberately a string so this contract does not own an external query language’s token enum.

Parameters:
  • left (QueryValue) – The left query value.

  • operator (str) – The backend-supported comparison operator.

  • right (QueryValue) – The right query value.

Returns:

The comparison predicate.

Return type:

QueryExpression

equal(left, right)[source]

Compare values using the backing’s ordinary stored semantics.

Parameters:
Returns:

The equality predicate.

Return type:

QueryExpression

exact_equal(left, right)[source]

Compare values in their exact canonical stored representation.

Parameters:
Returns:

The exact equality predicate.

Return type:

QueryExpression

is_null(value)[source]

Test a value for null; invert this predicate for a known-value test.

Parameters:

value (QueryValue) – The query value to test.

Returns:

The null-test predicate.

Return type:

QueryExpression

exists(scope, predicate)[source]

Test whether a correlated scope contains a row satisfying predicate.

Parameters:
  • scope (QueryScope) – The correlated scope to inspect.

  • predicate (QueryExpression) – The predicate required of a matching row.

Returns:

The existence predicate.

Return type:

QueryExpression

filtered(scope, predicate)[source]

Return the correlated subset of scope satisfying predicate.

The returned scope is usable by aggregate operations. In particular, it lets a declaration compare a required multiplicity with the exact number of matching child values rather than reusing one exists witness for repeated values.

Parameters:
  • scope (QueryScope) – The correlated scope to filter.

  • predicate (QueryExpression) – The predicate required of retained rows.

Returns:

A correlated scope containing only matching rows.

Return type:

QueryScope

count(scope)[source]

Return the number of rows in a correlated child/reference scope.

Parameters:

scope (QueryScope) – The correlated scope to count.

Returns:

A query value containing the row count.

Return type:

QueryValue

distinct_count(scope, value)[source]

Return the count of distinct value values in scope.

Parameters:
  • scope (QueryScope) – The correlated scope to count.

  • value (QueryValue) – The value whose distinct occurrences are counted.

Returns:

A query value containing the distinct count.

Return type:

QueryValue

scaled_exact_equal(left, left_factor, right, right_factor)[source]

Compare two exact values after cross multiplication.

This is the portable, exact form of a proportional comparison. It avoids requiring a backend to divide fractions or approximate a ratio through a presentation float: it asserts left * left_factor == right * right_factor in the backing’s canonical exact domain.

Parameters:
  • left (QueryValue) – The first exact value.

  • left_factor (QueryValue) – The factor applied to the first value.

  • right (QueryValue) – The second exact value.

  • right_factor (QueryValue) – The factor applied to the second value.

Returns:

The cross-multiplied equality predicate.

Return type:

QueryExpression

and_(*predicates)[source]

Conjoin predicates; an empty conjunction is always_true().

Parameters:

*predicates (QueryExpression) – The predicates to conjoin.

Returns:

The conjunction predicate.

Return type:

QueryExpression

or_(*predicates)[source]

Disjoin predicates; an empty disjunction is always_false().

Parameters:

*predicates (QueryExpression) – The predicates to disjoin.

Returns:

The disjunction predicate.

Return type:

QueryExpression

not_(predicate)[source]

Negate a predicate without relying on a backend’s Python truthiness.

Parameters:

predicate (QueryExpression) – The predicate to negate.

Returns:

The negated predicate.

Return type:

QueryExpression

when_known(known, predicate)[source]

Evaluate predicate only when known is true, else return unknown.

This is the backend-neutral three-valued-logic form of CASE WHEN known THEN predicate ELSE NULL END. It keeps incomplete nullable domain data unknown under both a predicate and its negation instead of silently treating the missing representation as a non-match.

Parameters:
  • known (QueryExpression) – The predicate establishing that the value is available.

  • predicate (QueryExpression) – The predicate evaluated only when known matches.

Returns:

The conditional three-valued predicate.

Return type:

QueryExpression

class httk.core.storage.QueryExpression[source]

Bases: Protocol

One backend-neutral boolean predicate.

Query callbacks compose predicates with the ordinary boolean operators; the backend decides how to retain SQL’s three-valued null semantics (or an equivalent semantics in another storage engine).

class httk.core.storage.QueryField[source]

Bases: QueryValue, Protocol

A durable field selected from a QueryScope.

exception httk.core.storage.QueryLiteralError[source]

Bases: ValueError

A query literal cannot represent the property value requested.

This is intentionally distinct from a query expression which simply matches no records. Protocol layers can translate it into their user-facing invalid-filter-value error without depending on a domain package’s parser exception.

class httk.core.storage.QueryScope[source]

Bases: Protocol

A record or correlated child/reference scope.

scope(name) follows a durable reference or child relationship while retaining correlation to this scope. It intentionally does not say whether that relationship is one-to-one or a collection: exists and the aggregate methods on QueryContext give both cases a single, portable vocabulary. Every scope call creates a distinct peer scope, even for the same relationship name, so a callback can compare correlated child rows without an accidental self-alias.

field(name)[source]

Return the durable scalar field named name in this scope.

Parameters:

name (str) – The durable field name.

Returns:

A query value representing that field.

Return type:

QueryField

scope(name)[source]

Return the correlated child or reference scope named name.

Parameters:

name (str) – The durable relationship name.

Returns:

A distinct correlated peer scope.

Return type:

QueryScope

class httk.core.storage.QueryValue[source]

Bases: Protocol

A scalar or aggregate value participating in a query expression.

class httk.core.storage.StoredPropertyProjection[source]

One domain-owned projection of a served property for one backing.

response is called with a concrete backing record and returns its protocol-boundary value. query receives a backend-neutral context, the protocol comparison operator, and its parsed literal; it returns a predicate or raises QueryLiteralError when the literal has no valid representation for this property. None means that a property is response-only for this backing. sort identifies a direct sortable value and is intentionally separate from filtering because not every predicate has a meaningful total ordering.

Parameters:
  • response – The operation that extracts the served value from a backing record.

  • query – The optional operation that builds filtering predicates.

  • sort – The optional operation that selects a value for ordering.

Raises:

TypeError – If a supplied projection operation cannot be invoked.

response: StoredPropertyResponse
query: StoredPropertyQuery | None = None
sort: StoredPropertySort | None = None
type httk.core.storage.StoredPropertyQuery = Callable[[QueryContext, str, object], QueryExpression][source]

Build one predicate from a context, protocol operator, and parsed literal.

type httk.core.storage.StoredPropertyResponse = Callable[[object], object][source]

Extract one served property value from one concrete backing record.

type httk.core.storage.StoredPropertySort = Callable[[QueryContext], QueryValue][source]

Select one sortable backing value from a query context.

httk.core.storage.stored_property_projections(cls)[source]

Return a validated property’s projection map declared on cls.

The lookup deliberately uses vars() rather than getattr(). A representation-specific property mapping must be opted into by the exact backing class; subclasses never inherit a parent’s mapping by accident. A class without the declaration serves no stored properties.

Parameters:

cls (type[Any]) – The exact frozen dataclass backing class to inspect.

Returns:

Its validated projection map, or an empty map when undeclared.

Raises:
  • TypeError – If cls is not a directly declared frozen dataclass or its map is invalid.

  • ValueError – If a projection name is invalid.

Return type:

collections.abc.Mapping[str, StoredPropertyProjection]