httk.store

Provide httk-store’s data-management capability layer for httk v2.

Built on the stdlib-only contracts and models in httk-core, httk-store supplies capabilities:

The providers self-register (under httk.registry.entries.store, as store-references/store-files/store-calculations/store-db-store) when httk.core discovers the module, so a serving module (such as httk-serve) can find them through the registry.

class httk.store.StandardEntryProvider

Submodules

Attributes

FilterTranslationCategory

Why a filter could not be translated (see FilterTranslationError).

Exceptions

FederatedSourceError

Report that a named source rejected or failed a federated operation.

FederatedStoreError

Report that a federation-level store operation failed.

IdLedgerError

An id ledger cannot be opened, verified, locked, or extended.

CountUnavailableError

Report that a store cannot provide an exact query count.

MultipleResultsError

Report that a result-set one() operation found multiple results.

NoResultError

Report that a result-set one() operation found no matching result.

PaginationCursorError

Report that a continuation cursor is malformed, expired, or belongs to another result plan.

UnsupportedQueryError

Report that a valid query operation is outside a store's supported profile.

FilterTranslationError

Report that a filter cannot be translated into a search expression.

EntryLayoutBindingError

A persisted application-owned layout needs explicit Python class bindings.

EntryIdConflictError

An entry id is already owned by a different lineage or alternative group.

PropertyValidationError

Report that a value did not conform to its OPTIMADE property definition.

Classes

CalculationEntryProvider

Serves OPTIMADE calculations from a mapping of id to Calculation.

DataRecordEntryProvider

Serve core DataRecord values as provider properties.

FileEntryProvider

Serves OPTIMADE files from a mapping of id to File.

ReferenceEntryProvider

Serves OPTIMADE references from a mapping of id to Reference.

RunEntryProvider

Serve core Run records and their provenance edges.

FederatedResultSet

Represent a frozen, lazy, re-iterable federated result plan.

FederatedSearcher

Build and validate one portable, single-root federated query.

FederatedStore

Fan out read-only queries over an ordered collection of borrowed stores.

FederatedTarget

Bind one logical target to exact concrete targets for named sources.

IdLedger

A signed, append-only allocator of stable entry ids for source keys.

ContinuationToken

Carry an opaque URL-safe continuation value.

PageableResultSetLike

Expose optional continuation-page capability on a frozen result set.

PageOrder

Order a continuation page by one named scalar result projection.

PortableQueryCapabilities

Describe the query operations guaranteed by one property definition.

ResultPage

Represent an immutable continuation-page result.

ResultRow

Represent one named result row by position, name, or attribute.

ResultRowLike

Require named access to one result row.

ResultSetLike

Require the common operations of a materialized result set.

Searcher

Build one query and iterate its results.

SearchExpression

Require composable backend search expressions.

SearchField

Expose a queryable field of a search variable.

SearchResult

Represent one match with declared output values and names.

SearchVariable

Bind a query variable to a target type whose attributes yield fields.

Store

Require a store that can create a query searcher.

EntryFamilyDeclaration

Declare one application-owned entry family without global registration.

EntryRecordDeclaration

Bind one stable store-local name to a concrete record class.

EntryIdScheme

Configuration used to mint human-readable entry identifiers.

EntryStore

The store surface consumed by httk.store.backend.sql.stored_federation.

Functions

product_relationships(links)

Build source-side relationships for a provider's relationships= argument.

export_dataset(store_path, out_path)

Export a snapshot-consistent SQLite store and its OPTIMADE definitions.

check_ledger_key(key)

Check a ledger source key, warning for deviations but never rejecting.

portable_query_capabilities(definition)

Derive the portable operation subset for definition.

portable_query_fields(entry_type, *[, include, exclude])

Return the ordered portable query fields described by entry_type.

filter_searcher(store, target, filter_string, *, ...)

Build a Searcher over store applying an OPTIMADE filter.

validate_property(definition, value)

Validate a single value against definition's JSON-Schema payload.

validate_record(entry_type, record)

Validate every property present in record against entry_type.

Package Contents

class httk.store.CalculationEntryProvider(entries, *, relationships=None)

Bases: StandardEntryProvider

Serves OPTIMADE calculations from a mapping of id to Calculation.

relationships optionally maps a calculation id to its related entries (RelatedEntry values, served flat per id) — e.g. its input/output files, expressed via the role metadata.

Parameters:
class httk.store.DataRecordEntryProvider(entries, *, definitions=None, relationships=None)

Bases: httk.core.EntryProvider

Serve core DataRecord values as provider properties.

Definitions are resolved eagerly at construction. Every served property name must start with _; absent record properties are emitted as JSON null.

Parameters:
Raises:

ValueError – If a property name, definition, or non-nullable property is inconsistent with the supplied records.

entry_types()

Return the resolved _httk_records entry definition.

Returns:

The served data-record entry-type definition.

Return type:

collections.abc.Mapping[str, httk.core.EntryTypeDefinition]

property_keys(entry_type)

Return served property names mapped to data-record keys.

Parameters:

entry_type (str) – The entry type to inspect.

Returns:

The served-property to record-key mapping.

Raises:

KeyError – If entry_type is not _httk_records.

Return type:

collections.abc.Mapping[str, str]

records(entry_type)

Return records with union-null values for unserved properties.

Parameters:

entry_type (str) – The entry type to enumerate.

Yield:

JSON-compatible records in input mapping order.

Raises:

KeyError – If entry_type is not _httk_records.

relationships(entry_type)

Return normalized data-record relationships by identifier.

Parameters:

entry_type (str) – The entry type to inspect.

Returns:

The relationship mapping supplied at construction.

Raises:

KeyError – If entry_type is not _httk_records.

Return type:

collections.abc.Mapping[str, tuple[httk.core.RelatedEntry, Ellipsis]]

class httk.store.FileEntryProvider(entries, *, relationships=None)

Bases: StandardEntryProvider

Serves OPTIMADE files from a mapping of id to File.

relationships optionally maps a file id to its related entries (RelatedEntry values, served flat per id) — e.g. the calculations a file is input/output of.

Parameters:
class httk.store.ReferenceEntryProvider(entries, *, relationships=None)

Bases: StandardEntryProvider

Serves OPTIMADE references from a mapping of id to Reference.

relationships optionally maps a reference id to its related entries (RelatedEntry values, served flat per id).

Parameters:
class httk.store.RunEntryProvider(entries)

Bases: httk.core.EntryProvider

Serve core Run records and their provenance edges.

Parameters:

entries (collections.abc.Mapping[str, httk.core.Run | collections.abc.Mapping[str, Any]]) – The runs keyed by their served identifiers.

entry_types()

Return the served _httk_runs entry definition.

The wire naming is the served form of the internal runs definition (see EntryTypeDefinition.served_form()).

Returns:

The served run entry-type definition.

Return type:

collections.abc.Mapping[str, httk.core.EntryTypeDefinition]

property_keys(entry_type)

Return the served run-property to record-key mapping.

Parameters:

entry_type (str) – The entry type to inspect.

Returns:

The served-property to record-key mapping.

Raises:

KeyError – If entry_type is not _httk_runs.

Return type:

collections.abc.Mapping[str, str]

records(entry_type)

Return JSON-compatible run records.

Parameters:

entry_type (str) – The entry type to enumerate.

Yield:

Run records in input mapping order.

Raises:

KeyError – If entry_type is not _httk_runs.

relationships(entry_type)

Return run provenance edges as forward semantic relationships.

Each edge is grouped under its owning field’s StrongLink forward relationship key in wire form (e.g. _httk_has_input, read from the markers on Run, not hardcoded). Run edges carry internal entry-type names; this serving edge translates each target type to its served (wire) name (via EntryTypeDefinition.served_form()), so a target such as records is served as _httk_records while standard type names pass through unchanged.

Parameters:

entry_type (str) – The entry type to inspect.

Returns:

Relationships grouped by run identifier.

Raises:

KeyError – If entry_type is not _httk_runs.

Return type:

collections.abc.Mapping[str, tuple[httk.core.RelatedEntry, Ellipsis]]

reverse_relationships()

Return the derived reverse view of the runs’ provenance edges.

Each run edge (entry_type, entry_id) yields a reverse related entry attached to the targeted entry: keyed by the target’s served (wire) entry type and its raw id, the related entry names this run under the edge field’s StrongLink reverse relationship key in wire form (e.g. _httk_is_input). Fields whose marker declares no reverse key contribute nothing.

Returns:

Related runs keyed by target entry type and then target entry id.

Return type:

collections.abc.Mapping[str, collections.abc.Mapping[str, tuple[httk.core.RelatedEntry, Ellipsis]]]

httk.store.product_relationships(links)

Build source-side relationships for a provider’s relationships= argument.

Feed the inner mapping into the source-side provider’s relationships= argument; per-edge workflow_declaration_uri is deliberately not served yet (relation-object serving is future work).

Parameters:

links (collections.abc.Iterable[httk.core.ProductLink]) – The product links to group by source type and identifier.

Returns:

Source-type mappings of source identifiers to related product entries.

Raises:

ValueError – If one source has duplicate product labels.

Return type:

dict[str, dict[str, tuple[httk.core.RelatedEntry, Ellipsis]]]

httk.store.export_dataset(store_path, out_path)

Export a snapshot-consistent SQLite store and its OPTIMADE definitions.

Parameters:
Returns:

The destination path.

Raises:

ValueError – If the store declaration has no resolvable definitions.

Return type:

pathlib.Path

class httk.store.FederatedResultSet(store, plan)

Represent a frozen, lazy, re-iterable federated result plan.

Results execute source-major in federation source order, preserve duplicate rows, and remain read-only views over the borrowed stores.

Parameters:
  • store (FederatedStore) – The federation whose sources execute the plan.

  • plan (object) – The validated frozen federation plan.

property names: tuple[str, Ellipsis]

Return the declared projection names.

Returns:

The result projection names in declaration order.

Return type:

tuple[str, Ellipsis]

first()

Return the first result row, or None when no row matches.

Returns:

The first matching row, or None.

Return type:

httk.store.query.ResultRow | None

one()

Return the only result row.

Returns:

The sole matching result row.

Raises:
Return type:

httk.store.query.ResultRow

scalars(name=None)

Iterate over one named projection.

Parameters:

name (str | None) – The projection name, required when more than one output exists.

Returns:

An iterator over the selected projection values.

Raises:
  • ValueError – If no name is supplied for multiple outputs.

  • KeyError – If name is not a declared output.

Return type:

collections.abc.Iterator[object]

column(name)

Return a lazy scalar column by projection name.

Parameters:

name (str) – The scalar projection name.

Returns:

A lazy column view over the projection.

Raises:
  • KeyError – If name is not a declared output.

  • TypeError – If name identifies an object output.

Return type:

FederatedResultColumn

abstractmethod cursor()

Reject cursor access because federation cursors are unsupported.

Returns:

Never returns.

Raises:

NotImplementedError – Always, because federated cursors are not implemented.

Return type:

collections.abc.Iterator[httk.store.query.ResultRow]

class httk.store.FederatedSearcher(store, *, as_of=None, only_latest=False)

Build and validate one portable, single-root federated query.

Parameters:
  • store (FederatedStore) – The federation whose child stores provide the query surface.

  • as_of (object) – Optional historic cutoff forwarded to child stores.

  • only_latest (bool) – Whether each child restricts root variables to the latest row of each lineage.

offset = 0
origin
variable(target)

Bind one shared or explicit target against child searcher prototypes.

Parameters:

target (object) – A shared child target or a source-specific target binding.

Returns:

The federated root variable.

Raises:
Return type:

FederatedVariable

add(expression)

Validate and retain a portable condition for the future frozen plan.

Parameters:

expression (object) – An expression produced by this searcher.

Returns:

None.

Raises:
Return type:

None

output(value, name)

Declare a record, scalar field, or origin output for a future plan.

Parameters:
  • value (object) – The root variable, field, or origin sentinel to project.

  • name (str) – The nonempty output name.

Returns:

None.

Raises:
Return type:

None

add_sort(field, descending=False)

Reject global sorting until a portable sort-semantics contract exists.

Parameters:
  • field (object) – The requested sort field.

  • descending (bool) – Whether the requested order is descending.

Raises:

httk.store.query.protocols.UnsupportedQueryError – Always, because global federation sorting has no portable contract.

count()

Return the exact unpaged count of the current filtered union.

Returns:

The exact sum of matching rows across participating sources.

Raises:
Return type:

int

set_limit(limit)

Set the global output limit; a negative value clears it.

Parameters:

limit (int) – The nonnegative limit, or a negative value to clear it.

Returns:

None.

Raises:

TypeError – If limit is not an integer.

Return type:

None

add_offset(offset)

Add a global source-union offset.

Parameters:

offset (int) – The nonnegative number of union rows to skip.

Returns:

None.

Raises:
Return type:

None

results(**outputs)

Freeze a projection plan into a lazy, re-iterable result set.

Parameters:

**outputs (object) – Optional output names mapped to root variables or fields.

Returns:

The lazy frozen result set.

Raises:
Return type:

FederatedResultSet

slicer(target)

A pandas-style [] indexing view over target records.

Each terminal indexing operation runs against a fresh federated searcher minted with this searcher’s as_of/only_latest scope, so slicer operations never share filter state. Slicer masks never sort, so the federation’s rejection of sorting does not apply.

Parameters:

target (object) – The stored record class to index.

Returns:

A slicer over target.

Return type:

httk.store.query.Slicer

exception httk.store.FederatedSourceError(source, operation)

Bases: FederatedStoreError

Report that a named source rejected or failed a federated operation.

Parameters:
  • source (str) – The source name that failed.

  • operation (str) – The federation operation being performed.

source
operation
class httk.store.FederatedStore(sources)

Fan out read-only queries over an ordered collection of borrowed stores.

The union is source-major, lazy, and non-deduplicating. Queries require the strict common query surface accepted by every participating source, and counts are exact sums of the unpaged source counts. This live borrowed-store view is distinct from the persisted registry in httk.store.backend.sql.stored_federation.

Parameters:

sources (collections.abc.Mapping[str, httk.store.query.Store]) – Child stores keyed by stable federation source name.

Raises:
  • TypeError – If sources is not a mapping.

  • ValueError – If fewer than two sources or an invalid source name is supplied.

property source_names: tuple[str, Ellipsis]

Return the immutable source names in constructor iteration order.

Returns:

The source names in constructor order.

Return type:

tuple[str, Ellipsis]

target(name, targets)

Create an immutable target mapping for an intentional source subset.

Parameters:
Returns:

The validated target binding.

Raises:
  • TypeError – If targets is not a mapping.

  • ValueError – If a target name or source name is invalid.

Return type:

FederatedTarget

searcher(*, as_of=None, only_latest=False)

Create an unbound federated searcher without touching child stores.

Parameters:
  • as_of (object) – Optional historic cutoff forwarded to every child store. A child that cannot honor it raises and the federation surfaces that child failure; this is a user-facing store API.

  • only_latest (bool) – Whether each child restricts root variables to the latest row of each lineage. A child that cannot honor it raises and the federation surfaces that child failure.

Returns:

A new mutable query builder.

Return type:

FederatedSearcher

exception httk.store.FederatedStoreError

Bases: RuntimeError

Report that a federation-level store operation failed.

class httk.store.FederatedTarget

Bind one logical target to exact concrete targets for named sources.

Parameters:
  • name – The nonempty logical target name.

  • targets – Concrete targets keyed by federation source name.

  • _owner – The federation that owns this target binding.

Raises:
  • TypeError – If targets is not a mapping or _owner is not a federation.

  • ValueError – If the name, source set, or source names are invalid.

name: str
targets: collections.abc.Mapping[str, object]
class httk.store.IdLedger(path, *, bases, series, ledger_uuid, keys, records, live, persisted, segments)

A signed, append-only allocator of stable entry ids for source keys.

Open one with create() or open() and use it as a context manager; the enclosing with holds an exclusive lock and, on exit, appends and signs one new segment only when something was assigned or aliased. Callers use those constructors rather than the initializer, which binds an already-validated state to its file and lock.

Parameters:
  • path (pathlib.Path) – The ledger sqlite database path.

  • bases (dict[str, str]) – The per-family id bases, keyed by family name.

  • series (str) – The id series every minted id carries.

  • ledger_uuid (str) – This ledger’s identity, stamped into every segment subject.

  • keys (collections.abc.Sequence[tuple[str, bytes]]) – The signing keys used to sign the next segment on close, each a (role, seed) pair.

  • records (list[dict[str, str]]) – The ordered ledger records, each a {key, ...} mapping.

  • live (dict[str, dict[str, str]]) – The newest record per key, the key’s live binding.

  • persisted (int) – How many records are already stored on disk.

  • segments (int) – How many segments are already stored on disk.

classmethod create(path, *, bases, series, keys)

Create and sign a fresh, empty ledger, then hold it open and locked.

The fresh database carries segment 1: an empty segment (no records) whose signed subject stamps the initial bases, so the ledger is signed from birth.

Parameters:
Returns:

The open, locked ledger.

Raises:
  • IdLedgerError – If the ledger already exists or the lock is held.

  • ValueError – If a base or the series is malformed.

Return type:

IdLedger

classmethod open(path, *, keys=(), trusted_keys=(), verify=True, bases=None, series=None)

Open an existing ledger, verifying its signatures and invariants.

With verify, every segment’s signature is checked: an INVALID signature (content that no longer matches its own segment) always raises, while a valid one is treated as an audit record — trusted_keys demand a trusted signer on every segment, and without them the valid signers are logged. The structure and every entry invariant are validated regardless (segment ranges must partition the records exactly, bases must grow monotonically, ids must conform, supersession must be sound), because a signature attests only to the bytes, not to their meaning.

When series is given it must equal the stored series. When bases is given it is reconciled as a SUPERSET of the stored map: every stored family must appear in it with the same base (removing, renaming, or re-basing a stored family is an error), while families present only in the expectation are ADDED and stamped into the next segment’s subject at close (so a build that assigns nothing but grows the scheme still writes on close). The merged map is revalidated for id shape and base uniqueness.

Parameters:
  • path (str | os.PathLike[str]) – The ledger database to open.

  • keys (collections.abc.Sequence[tuple[str, bytes]]) – The signing keys used to sign the next segment on close.

  • trusted_keys (collections.abc.Sequence[str]) – Trust anchors as ed25519: keys or sha256: fingerprints; when given, every segment’s signer must be one of them.

  • verify (bool) – Whether to verify the segment signatures.

  • bases (collections.abc.Mapping[str, str] | None) – The per-family bases the caller expects, asserted when given.

  • series (str | None) – The id series the caller expects, asserted when given.

Returns:

The open, locked ledger.

Raises:

IdLedgerError – If the ledger is missing, the lock is held, verification fails, an invariant is violated, or the expected bases/series disagree.

Return type:

IdLedger

assign(key, family, *, supersede=False)

Return the id for a source key, minting one on first sight.

The call is idempotent: a key already assigned in this family returns its existing id. A key assigned in another family is an error, and an aliased key is an error unless supersede re-binds it.

With supersede=True on a currently-aliased key, a fresh assignment is appended carrying supersedes=<the alias target> and a newly minted id — the split half of source regrouping. supersede=True on an already-assigned key is an error: an assignment is never re-bound to another assignment.

Parameters:
  • key (str) – The stable source key.

  • family (str) – The id family the key belongs to.

  • supersede (bool) – Whether to re-bind an aliased key to a fresh assignment.

Returns:

The assigned entry id.

Raises:

IdLedgerError – If the key is aliased and supersede is false, its family disagrees, the family has no base, or supersede is passed outside its one transition (a new key, or an already-assigned key).

Return type:

str

alias(key, existing_id, *, supersede=False)

Record a source key pointing at an id already in the ledger.

Aliases exist because the store deduplicates content-identical rows family-wide: several keys can reach one row, which must keep one id. The call is idempotent for an identical (key, existing_id) pair; a conflicting re-alias, or targeting an id absent from the ledger, is an error, and so is aliasing an already-assigned key unless supersede re-binds it.

With supersede=True on a currently-assigned key, an alias record is appended carrying supersedes=<its old id> — the merge half of source regrouping. The old id stays reserved and stays resolvable while any other key points at it, otherwise becoming a harmless orphan.

Parameters:
  • key (str) – The stable source key to record.

  • existing_id (str) – An id already assigned in the ledger.

  • supersede (bool) – Whether to re-bind an assigned key to an alias.

Raises:

IdLedgerError – On a conflict, an unknown target, an assigned key when supersede is false, or supersede passed for a new key.

lookup(key)

Return the id a source key resolves to, following an alias.

Resolution is to the key’s newest record, so a superseded binding is never returned for the key that moved on from it.

Parameters:

key (str) – The source key to resolve.

Returns:

The assigned id, or None when the key is unknown.

Return type:

str | None

close()

Append and sign a new segment when the ledger changed, then unlock.

A ledger untouched since it was opened is left byte-identical: no connection is opened and nothing is written, so an idempotent rebuild produces no git churn. A dirty close with no signing key available raises from the sealing layer before anything is written; a failed close leaves the ledger unclosed and its lock held, so a retried close reattempts the write instead of silently skipping it (the manual remedy for an abandoned session is to delete the lock).

exception httk.store.IdLedgerError

Bases: RuntimeError

An id ledger cannot be opened, verified, locked, or extended.

This covers both the cannot proceed cases — a held lock, a signature or invariant that does not verify — and the API-misuse cases — assigning an aliased key without superseding, or aliasing a key to an id absent from the ledger.

httk.store.check_ledger_key(key)

Check a ledger source key, warning for deviations but never rejecting.

Ledger keys are opaque to the allocator: the standardized grammar is a convention enforced only by the workflow helpers, so this mirrors httk.core.entry_ids.check_entry_id in stance but, unlike it, never raises — it only warns on leading/trailing whitespace or non-URL-safe characters.

Parameters:

key (str) – The source key to check.

Returns:

The unchanged key.

Return type:

str

class httk.store.ContinuationToken

Bases: str

Carry an opaque URL-safe continuation value.

It is a str subclass so normal JSON serializers preserve it as a scalar value. Applications should pass a token returned by a page back unchanged; data backends validate its version, structure, and result-plan fingerprint before using any decoded value as a bound parameter.

Parameters:

value – The opaque continuation value.

exception httk.store.CountUnavailableError

Bases: RuntimeError

Report that a store cannot provide an exact query count.

exception httk.store.MultipleResultsError

Bases: LookupError

Report that a result-set one() operation found multiple results.

exception httk.store.NoResultError

Bases: LookupError

Report that a result-set one() operation found no matching result.

class httk.store.PageableResultSetLike

Bases: Protocol

Expose optional continuation-page capability on a frozen result set.

This deliberately extends neither ResultSetLike nor Searcher: stores that do not support seek pagination remain fully conforming to the required portable contracts.

page(*, size, order_by, cursor=None, include_total=False)

Return one ordered continuation page.

class httk.store.PageOrder

Order a continuation page by one named scalar result projection.

name identifies the name supplied to results() (or Searcher.output()), never a backend column object. The result-set implementation validates that it is a root scalar projection before it generates SQL.

Parameters:
  • name – The declared scalar output name used for ordering.

  • descending – Whether to order this field in descending order.

  • nulls – Whether null values sort first or last.

name: str
descending: bool = False
nulls: Literal['first', 'last'] = 'last'
exception httk.store.PaginationCursorError

Bases: ValueError

Report that a continuation cursor is malformed, expired, or belongs to another result plan.

class httk.store.PortableQueryCapabilities

Describe the query operations guaranteed by one property definition.

query-support expresses a cross-provider guarantee, not a particular server’s implementation detail. all optional is deliberately fail-closed here: it gives a portable client no operation it can rely on. A server may offer more, but that is not represented by the definition.

Parameters:
  • query_support – The normalized declared query-support level.

  • operations – The portable operation families guaranteed by the definition.

query_support: str | None
operations: frozenset[str]
supports(operation)

Report whether operation is guaranteed by this definition.

Parameters:

operation (str) – The operation family to test.

Returns:

True when the operation is portable.

Return type:

bool

class httk.store.ResultPage

Represent an immutable continuation-page result.

rows is always a tuple. Returned rows are ordinary persistent result rows, not the expiring proxies produced by SqlResultSet.cursor(). total is populated only when the caller explicitly asks for it.

Parameters:
  • rows – The persistent rows returned by the page.

  • next – The token for the next page, if one exists.

  • previous – The token for the previous page, if one exists.

  • total – The exact result count when requested, otherwise None.

rows: tuple[ResultRowLike, Ellipsis]
next: ContinuationToken | None
previous: ContinuationToken | None
total: int | None = None
class httk.store.ResultRow(values, names, resolver=None, guard=None)

Represent one named result row by position, name, or attribute.

Parameters:
  • values (tuple[Any, Ellipsis]) – The row values in declaration order.

  • names (tuple[str, Ellipsis]) – The corresponding output names.

  • resolver (Any) – An optional lazy value resolver.

  • guard (Any) – An optional callback that rejects access to expired values.

property names: tuple[str, Ellipsis]

Return the declared output names.

property values: tuple[Any, Ellipsis]

Return the row values in declaration order.

class httk.store.ResultRowLike

Bases: Protocol

Require named access to one result row.

property names: tuple[str, Ellipsis]

Return the row’s declared output names.

class httk.store.ResultSetLike

Bases: Protocol

Require the common operations of a materialized result set.

first()

Return the first row, or None when no row matches.

one()

Return the only row, or raise when the count is not one.

scalars(name=None)

Iterate over one named scalar output.

class httk.store.Searcher

Bases: Protocol

Build one query and iterate its results.

Iteration yields one SearchResult per match, so item[0][0] is the first declared output of the match (typically the matched row object). The expressions received by add are always ones produced by this same backend’s search variables, so implementations may type them as their own expression class; a backend that needs a second (post-filter) evaluation position decides that from the expression itself, not from the caller.

offset: int
variable(target)

Bind a query variable to target.

output(variable, name)

Declare variable as a named result output.

add(expression)

Add a filter expression to the query.

count()

Return the exact count of the current query.

set_limit(limit)

Set the query limit.

add_offset(offset)

Add an offset to the query.

add_sort(field, descending)

Add a field sort to the query.

results(**outputs)

Return a result set for the requested named outputs.

class httk.store.SearchExpression

Bases: Protocol

Require composable backend search expressions.

class httk.store.SearchField

Bases: Protocol

Expose a queryable field of a search variable.

In addition to the methods below, fields support the rich comparison operators (==, !=, <, <=, >, >=), returning SearchExpression. The handlers invoke those via getattr(field, '__eq__')(value) since the comparison dunders cannot be typed as expression-returning.

The three string-matching methods take literal text: no wildcard or pattern syntax whatsoever crosses this contract, so % and _ (and any other metacharacter) match themselves. A backend is therefore free to implement them with SQL LIKE over an escaped pattern, with a regular expression, or with a full-text index — the choice is invisible here.

has(value)

Match a list field containing value.

has_any(*values)

Match a list field containing any of values.

has_only(*values)

Match a list field containing no values outside values.

is_in(*values)

Match a root scalar field whose value is one of values.

None is an explicit member: it matches a null field value, and its negation excludes nulls rather than inheriting SQL’s three-valued NOT IN (..., NULL) behavior.

Backends define the corresponding semantics for child or set fields; for example, a backend may use the existing has_only-style all-values reading for a child field.

contains(text)

Match values containing text as a literal substring.

startswith(prefix)

Match values beginning with the literal prefix.

endswith(suffix)

Match values ending with the literal suffix.

class httk.store.SearchResult

Bases: NamedTuple

Represent one match with declared output values and names.

values holds one entry per Searcher.output() call in declaration order; it is a tuple, so values, names = result and result[0][0] both work.

values: tuple[Any, Ellipsis]
names: tuple[str, Ellipsis]
class httk.store.SearchVariable

Bases: Protocol

Bind a query variable to a target type whose attributes yield fields.

always_true/always_false are reserved names: they are real methods of the variable, never stored fields resolved through __getattr__. They exist so a translation layer can express a constant truth value without inventing a probe field. A field == field probe is NULL-unsound, since it yields NULL (not true) for a NULL field.

always_true()

An expression that matches every row.

always_false()

An expression that matches no row.

class httk.store.Store

Bases: Protocol

Require a store that can create a query searcher.

Implementations predating the as_of keyword may omit it and remain usable for current-state queries, but cannot honor historic queries.

searcher(*, as_of=None)

Create an empty searcher, optionally at a historic cutoff.

Parameters:

as_of (object) – Optional canonical historic timestamp cutoff.

Returns:

An empty query searcher.

Return type:

Searcher

exception httk.store.UnsupportedQueryError

Bases: ValueError

Report that a valid query operation is outside a store’s supported profile.

httk.store.portable_query_capabilities(definition)

Derive the portable operation subset for definition.

The operation names are "equality", "ordering", "stringmatching", and "set". They intentionally describe the query-language operation families rather than storage implementation. IS [NOT] KNOWN is part of the equality family because it is the NULL spelling of equality/inequality in the OPTIMADE filter language.

Parameters:

definition (httk.core.PropertyDefinition) – The OPTIMADE property definition to inspect.

Returns:

The guaranteed portable query capabilities.

Return type:

PortableQueryCapabilities

httk.store.portable_query_fields(entry_type, *, include=(), exclude=())

Return the ordered portable query fields described by entry_type.

By default, this selects scalar fields and flat lists with at least one operation guaranteed by their definition. include is an explicit binding override for named existing properties; it is appended as a second ordered group after the derived fields, in entry-definition order among the included names, but does not manufacture query capabilities absent from that definition. exclude always wins. Both arguments reject unknown or duplicate names so binding mistakes cannot silently broaden a profile.

Parameters:
Returns:

Derived property names followed by explicitly included names.

Raises:

ValueError – If include or exclude contains an unknown or duplicate property name.

Return type:

tuple[str, Ellipsis]

type httk.store.FilterTranslationCategory = Literal['unrecognized-property', 'not-implemented', 'type-mismatch', 'internal']

Why a filter could not be translated (see FilterTranslationError).

exception httk.store.FilterTranslationError(message, category, detail=None)

Bases: Exception

Report that a filter cannot be translated into a search expression.

The exception message describes the failure; category classifies it neutrally (this module knows nothing about transports, so consumers map each category onto their own error codes):

  • "unrecognized-property" — the filter names an unknown property carrying a recognized prefix (a caller error);

  • "type-mismatch" — a filter constant does not match the property’s declared type (a caller error);

  • "not-implemented" — the filter uses a construct this translation (or the supplied handler table) does not support;

  • "internal" — an inconsistency in the translation itself.

detail optionally carries extra machine-readable context.

Parameters:
  • message (str) – The human-readable translation failure.

  • category (FilterTranslationCategory) – The neutral failure category.

  • detail (str | None) – Optional machine-readable failure context.

category: FilterTranslationCategory
detail = None
httk.store.filter_searcher(store, target, filter_string, *, entry_type, property_fulltypes, property_keys=None, handlers=None, recognized_prefixes=(), relationship_targets=(), related_property_resolver=None)

Build a Searcher over store applying an OPTIMADE filter.

filter_string is an OPTIMADE filter string (parsed with httk.core.optimade.parse_optimade_filter()) or an already-parsed FilterAst. The searcher binds one search variable to target (the store-specific query target, declared as the searcher output named entry_type) and applies the translated filter. When handlers is not supplied, a default table is built with simple_property_handlers() from property_keys (or, when property_keys is also None, from an identity map over property_fulltypes). The remaining keyword arguments are passed through to translate_filter_ast().

Parameters:
  • store (httk.store.query.Store) – The backend store on which to build the searcher.

  • target (Any) – The backend query target to bind.

  • filter_string (str | httk.core.optimade.FilterAst) – An OPTIMADE filter string or parsed filter AST.

  • entry_type (str) – The output name and served entry type.

  • property_fulltypes (collections.abc.Mapping[str, str]) – Fulltypes keyed by recognized property name.

  • property_keys (collections.abc.Mapping[str, str] | None) – Optional mapping from property names to backend field names.

  • handlers (HandlerTable | None) – Optional prebuilt property handler table.

  • recognized_prefixes (tuple[str, Ellipsis]) – Prefixes whose unknown properties are errors.

  • relationship_targets (tuple[str, Ellipsis]) – Related entry types that support dotted filters.

  • related_property_resolver (RelatedPropertyResolver | None) – Optional resolver for related-property filters.

Returns:

A searcher with the translated filter already applied.

Raises:
Return type:

httk.store.query.Searcher

class httk.store.EntryFamilyDeclaration

Declare one application-owned entry family without global registration.

Explicit declarations provide stable persistence identities directly to a store. They are intended for application-private families which should not participate in plugin discovery. The same declaration must be supplied whenever such a store is reopened.

Parameters:
  • name – Stable family identity persisted in the store declaration.

  • family – Logical entry-family class exposed through entry_layout.

  • records – Ordered concrete record declarations belonging to the family.

  • definition_id – Optional entry-type definition IRI for the family.

name: str
family: type
records: tuple[EntryRecordDeclaration, Ellipsis]
definition_id: str | None = None
exception httk.store.EntryLayoutBindingError

Bases: ValueError

A persisted application-owned layout needs explicit Python class bindings.

class httk.store.EntryRecordDeclaration

Bind one stable store-local name to a concrete record class.

Parameters:
  • name – Stable record identity persisted in the store declaration.

  • record – Concrete frozen dataclass used for storage and hydration.

  • definition_id – Optional entry-type definition IRI described by the record.

name: str
record: type
definition_id: str | None = None
exception httk.store.EntryIdConflictError(table_name, entry_id, existing_logical_id, requested_logical_id)

Bases: ValueError

An entry id is already owned by a different lineage or alternative group.

Parameters:
  • table_name (str) – The table containing the conflicting identifier.

  • entry_id (str) – The conflicting entry identifier.

  • existing_logical_id (int | None) – The lineage or group already owning the identifier.

  • requested_logical_id (int | None) – The lineage or group requesting it, when known.

table_name
entry_id
existing_logical_id
requested_logical_id
class httk.store.EntryIdScheme

Configuration used to mint human-readable entry identifiers.

Parameters:
  • base – Dot-separated database namespace.

  • series – Campaign-series token.

  • type_in_base – Whether the served entry type is appended to base.

base: str
series: str
type_in_base: bool = False
class httk.store.EntryStore

Bases: Protocol

The store surface consumed by httk.store.backend.sql.stored_federation.

This protocol deliberately describes the small backend seam used by the federation. The stored-property plan and candidate-stream objects remain backend-specific; their SQL implementations use searcher().

property entry_layout: tuple[httk.store.storage_layout.EntryFamilyLayout, Ellipsis]

Return the configured entry-family layouts in stable order.

searcher(*, as_of=None)

Return a backend searcher used to build candidate ID streams.

fetch(cls, sid, *, eager=False)

Fetch the stored record of cls identified by sid.

Parameters:
  • cls (type[_StoredRecord]) – The storable record class.

  • sid (int) – The stored row identifier to fetch.

  • eager (bool) – Whether to fully materialize the record instead of returning a lazy row.

Returns:

The reconstructed instance.

Return type:

_StoredRecord

fetch_many(cls, sids, *, eager=False)

Fetch the stored records of cls identified by sids.

Batched counterpart of fetch().

Parameters:
  • cls (type[_StoredRecord]) – The storable record class.

  • sids (collections.abc.Sequence[int]) – The stored row identifiers to fetch.

  • eager (bool) – Whether to fully materialize each record instead of returning lazy rows.

Returns:

The reconstructed instances in sids order.

Raises:

KeyError – When any requested row is absent.

Return type:

list[_StoredRecord]

stored_property_plan(family)

Return the backend-specific stored-property plan for one family.

Parameters:

family (type) – The logical entry-family class to plan.

Returns:

The validated stored-property plan consumed by federation.

Return type:

Any

exception httk.store.PropertyValidationError(name, message)

Bases: ValueError

Report that a value did not conform to its OPTIMADE property definition.

Carries the offending property name and a human-readable message. For single-value failures the message wraps the underlying jsonschema error message, and that jsonschema.exceptions.ValidationError is preserved as the chained __cause__.

Parameters:
  • name (str) – The name of the invalid property.

  • message (str) – The validation failure message.

name
message
httk.store.validate_property(definition, value)

Validate a single value against definition’s JSON-Schema payload.

Builds a jsonschema.Draft202012Validator directly from the definition’s document (with the $schema meta-schema reference removed) and validates value against it using the local format checker. Returns None on success; raises PropertyValidationError on failure, chaining the underlying jsonschema.exceptions.ValidationError as the cause. No network access or registry lookup ever happens.

Parameters:
Returns:

None.

Raises:

PropertyValidationError – If value violates definition.

Return type:

None

httk.store.validate_record(entry_type, record)

Validate every property present in record against entry_type.

Each key in record must be described by entry_type; unknown property names are rejected with a PropertyValidationError naming them and the entry type. id and type must both be present. Properties described by the definition but absent from record are simply not checked (serving a subset of the described properties is normal). The value of every property that is present is validated via validate_property(). Returns None on success.

Parameters:
Returns:

None.

Raises:

PropertyValidationError – If a property is unknown, id or type is missing, or a value violates its property definition.

Return type:

None