httk.store.query.optimade_filters¶
Translate OPTIMADE filter syntax trees into backend search expressions.
This module turns the OPTIMADE filter language — parsed by
httk.core.optimade.parse_optimade_filter() into a httk.core.optimade.FilterAst
nested-tuple syntax tree — into SearchExpression
objects over the backend-agnostic store/searcher protocols of
httk.store.query. It is pure and store-independent: any
Store whose search variables expose the queried
fields can execute the translated expressions.
The translation is driven by three inputs:
property_fulltypes— a minimal mapping from recognized property names to their OPTIMADEfulltypestrings ("string","integer","float","boolean","timestamp","dict","unknown", or"list of ..."), used to type-check and convert filter constants;handlers— aHandlerTablemapping property names to the callables that build the actual search expressions (seesimple_property_handlers()for the generic property-key-driven builder, andrelationship_id_handler()for<type>.idrelationship entries);recognized_prefixes— property-name prefixes the serving side claims: an unknown property carrying such a prefix is an error ("unrecognized-property"), while any other unknown property silently matches nothing, as the OPTIMADE specification prescribes.
Failures raise FilterTranslationError, which carries a neutral
category (no HTTP semantics); consumers map categories onto their
transport’s error codes.
Relationship filtering (dotted identifiers such as references.doi) is
supported for relationship types named in relationship_targets:
<type>.id HAS ... translates directly through the handler table, and any
other depth-1 dotted filter is resolved by a two-phase semi-join through a
supplied RelatedPropertyResolver (see translate_filter_ast()).
Each dotted filter node is resolved independently: in references.doi
CONTAINS "x" AND references.year >= 2000, some related reference must match
the doi condition and some (possibly different) related reference must match
the year condition.
Attributes¶
Why a filter could not be translated (see |
|
Per-property translation callables, keyed by property name. |
|
Resolve a depth-1 relationship filter to the matching related-entry ids. |
|
Parsed filter token kinds that represent literal constants. |
|
Comparison operators after swapping a constant from left to right. |
Exceptions¶
Report that a filter cannot be translated into a search expression. |
Functions¶
|
Convert a filter constant node to a Python value of the property's |
|
Build a constant-true expression over |
|
Build a constant-false expression over |
|
Translate unknown-value tests for an unrecognized property. |
|
Translate known-value tests for a property with known nullability. |
|
Test nullability against the mapped backend field. |
|
Build a false expression for comparison on an unknown property. |
|
Build a false expression for string matching on an unknown property. |
|
Build a false expression for set filtering on an unknown property. |
|
Build a false expression for length filtering on an unknown property. |
|
Translate a scalar comparison onto a backend field. |
|
Translate |
|
Fold |
|
Fold |
|
Translate a numeric comparison onto a backend field. |
|
Normalize an RFC 3339 timestamp and translate its comparison. |
|
Translate one HAS family node over the list-valued field |
|
Fold a HAS-family operation over two constant sets. |
|
Translate one filter syntax-tree node into a search expression. |
|
Build a filter handler table for an entry type from a property-key map. |
|
A |
|
Build a |
Module Contents¶
- type httk.store.query.optimade_filters.FilterTranslationCategory = Literal['unrecognized-property', 'not-implemented', 'type-mismatch', 'internal'][source]¶
Why a filter could not be translated (see
FilterTranslationError).
- type httk.store.query.optimade_filters.HandlerTable = Mapping[str, Mapping[str, Callable[..., Any]]][source]¶
Per-property translation callables, keyed by property name.
The inner mapping’s keys name the filter-operation families:
'comparison'(=,!=,<,<=,>,>=),'stringmatching'(CONTAINS/STARTS/ENDS),'HAS'(the set operations),'length'(LENGTH), and'unknown'(IS KNOWN/IS UNKNOWN). A'HAS'handler is called ashandler(property, ops, values, search_variable, has_type)and returns a plainSearchExpression. The caller appliesNOTas~; handlers do not receive negation state or report post-filter placement. Dotted'<type>.id'entries provide relationship-id filtering (seerelationship_id_handler()).
- type httk.store.query.optimade_filters.RelatedPropertyResolver = Callable[[str, FilterAst], tuple[str, ...]][source]¶
Resolve a depth-1 relationship filter to the matching related-entry ids.
Called as
resolver(related_type, sub_ast)wheresub_astis the filter node with the<related_type>.prefix stripped from its identifier (and without any surroundingNOT); returns the ids of the related entries matching the sub-filter, evaluated against the related type’s own properties.
- exception httk.store.query.optimade_filters.FilterTranslationError(message, category, detail=None)[source]¶
Bases:
ExceptionReport that a filter cannot be translated into a search expression.
The exception message describes the failure;
categoryclassifies 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.
detailoptionally 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[source]¶
- httk.store.query.optimade_filters.constant_types = ('String', 'Number', 'Boolean')[source]¶
Parsed filter token kinds that represent literal constants.
- httk.store.query.optimade_filters.invert_op[source]¶
Comparison operators after swapping a constant from left to right.
- httk.store.query.optimade_filters.format_value(fulltype, val, allow_null=False)[source]¶
Convert a filter constant node to a Python value of the property’s
fulltype.- Parameters:
- Returns:
The converted Python filter value.
- Raises:
FilterTranslationError – With category
"type-mismatch"when the constant does not fit the declared type, or"not-implemented"for dictionary-typed properties.- Return type:
Any
- httk.store.query.optimade_filters.true_handler(search_variable)[source]¶
Build a constant-true expression over
search_variable.- Parameters:
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
- Returns:
An expression that matches every row.
- Return type:
- httk.store.query.optimade_filters.false_handler(search_variable)[source]¶
Build a constant-false expression over
search_variable.- Parameters:
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
- Returns:
An expression that matches no row.
- Return type:
- httk.store.query.optimade_filters.unknown_unknown_handler(entry, search_variable, unknown_type)[source]¶
Translate unknown-value tests for an unrecognized property.
- Parameters:
entry (str) – The property name, retained for handler compatibility.
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
unknown_type (str) – The
IS_KNOWNorIS_UNKNOWNoperator.
- Returns:
The corresponding constant expression.
- Raises:
FilterTranslationError – If
unknown_typeis not supported.- Return type:
- httk.store.query.optimade_filters.known_unknown_handler(entry, search_variable, unknown_type)[source]¶
Translate known-value tests for a property with known nullability.
- Parameters:
entry (str) – The property name, retained for handler compatibility.
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
unknown_type (str) – The
IS_KNOWNorIS_UNKNOWNoperator.
- Returns:
The corresponding constant expression.
- Raises:
FilterTranslationError – If
unknown_typeis not supported.- Return type:
- httk.store.query.optimade_filters.field_unknown_handler(entry, search_variable, unknown_type)[source]¶
Test nullability against the mapped backend field.
- Parameters:
entry (str) – The backend field name to inspect.
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
unknown_type (str) – The
IS_KNOWNorIS_UNKNOWNoperator.
- Returns:
The nullability expression for the field.
- Raises:
FilterTranslationError – If
unknown_typeis not supported.- Return type:
- httk.store.query.optimade_filters.unknown_comparison_handler(entry, ops, values, search_variable)[source]¶
Build a false expression for comparison on an unknown property.
- Parameters:
entry (str) – The unknown property name.
ops (Any) – The parsed comparison operators.
values (Any) – The parsed comparison values.
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
- Returns:
An expression that matches no row.
- Return type:
- httk.store.query.optimade_filters.unknown_stringmatching_handler(entry, values, stringmatching_type, search_variable)[source]¶
Build a false expression for string matching on an unknown property.
- Parameters:
entry (str) – The unknown property name.
values (Any) – The parsed match value.
stringmatching_type (str) – The parsed string-matching operator.
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
- Returns:
An expression that matches no row.
- Return type:
- httk.store.query.optimade_filters.unknown_has_handler(entry, op, value, search_variable, has_type)[source]¶
Build a false expression for set filtering on an unknown property.
- Parameters:
entry (str) – The unknown property name.
op (Any) – The parsed set operators.
value (Any) – The parsed set values.
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
has_type (str) – The parsed HAS-family operator.
- Returns:
An expression that matches no row.
- Return type:
- httk.store.query.optimade_filters.unknown_length_handler(entry, op, value, search_variable)[source]¶
Build a false expression for length filtering on an unknown property.
- Parameters:
entry (str) – The unknown property name.
op (str) – The parsed length comparison operator.
value (Any) – The parsed length value.
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
- Returns:
An expression that matches no row.
- Return type:
- httk.store.query.optimade_filters.string_handler(entry, op, value, search_variable)[source]¶
Translate a scalar comparison onto a backend field.
- Parameters:
entry (str) – The backend field name.
op (str) – The comparison operator.
value (Any) – The converted filter value.
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
- Returns:
The field comparison expression.
- Return type:
- httk.store.query.optimade_filters.stringmatching_handler(entry, value, stringmatching_type, search_variable)[source]¶
Translate
CONTAINS/STARTS/ENDSonto the field’s literal matchers.The filter constant is passed through unescaped: the search-field protocol’s
contains/startswith/endswithtake literal text, so%and_match themselves (as OPTIMADE requires). Any escaping a backend’s pattern language needs is that backend’s own business.- Parameters:
entry (str) – The backend field name.
value (str) – The literal filter text.
stringmatching_type (str) – The
CONTAINS,STARTS, orENDSoperator.search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
- Returns:
The literal string-matching expression.
- Raises:
FilterTranslationError – If
stringmatching_typeis not supported.- Return type:
- httk.store.query.optimade_filters.constant_comparison_handler(val1, op, val2, search_variable)[source]¶
Fold
val1 <op> val2(both constants) to a constant expression.val1is the value being compared andval2the filter constant, the same left-to-right convention asconstant_set_handler();translate_filter_ast()has already invertedopfor constant-on-the-left filters, so this ordering is the filter’s own.- Parameters:
val1 (Any) – The value being compared.
op (str) – The comparison operator.
val2 (Any) – The filter constant.
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
- Returns:
A constant expression representing the comparison result.
- Return type:
- httk.store.query.optimade_filters.constant_stringmatching_handler(val1, val2, stringmatching_type, search_variable)[source]¶
Fold
val1 <CONTAINS|STARTS|ENDS> val2(both constants) to a constant expression.val1is the value being matched andval2the filter text, the same left-to-right convention asconstant_set_handler().- Parameters:
val1 (Any) – The value being matched.
val2 (Any) – The filter text.
stringmatching_type (str) – The
CONTAINS,STARTS, orENDSoperator.search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
- Returns:
A constant expression representing the match result.
- Raises:
FilterTranslationError – If
stringmatching_typeis not supported.- Return type:
- httk.store.query.optimade_filters.number_handler(entry, op, value, search_variable)[source]¶
Translate a numeric comparison onto a backend field.
- Parameters:
entry (str) – The backend field name.
op (str) – The comparison operator.
value (Any) – The converted numeric filter value.
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
- Returns:
The field comparison expression.
- Return type:
- httk.store.query.optimade_filters.timestamp_handler(entry, op, value, search_variable)[source]¶
Normalize an RFC 3339 timestamp and translate its comparison.
- Parameters:
entry (str) – The backend field name.
op (str) – The comparison operator.
value (Any) – The RFC 3339 timestamp filter value.
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
- Returns:
The normalized timestamp comparison expression.
- Raises:
FilterTranslationError – If
valueis not an offset-aware RFC 3339 timestamp.- Return type:
- httk.store.query.optimade_filters.set_handler(entry, ops, values, has_type, search_variable)[source]¶
Translate one HAS family node over the list-valued field
entry.HAS ALLbecomes a conjunction of one-valuehas_anycalls (each constraining an independently joined child row);HAS ANYandHAS ONLYmap straight ontohas_any/has_only. Negation is not the handler’s business: a surroundingNOTinverts the returned expression, and the backend’s~knows how to negate a set predicate.- Parameters:
entry (str) – The backend list-valued field name.
ops (Any) – The parsed set comparison operators.
values (Any) – The converted set values.
has_type (str) – The HAS-family operator.
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
- Returns:
The list-membership expression.
- Raises:
FilterTranslationError – If
has_typeis not supported.- Return type:
- httk.store.query.optimade_filters.constant_set_handler(val1, ops, val2, has_type, search_variable)[source]¶
Fold a HAS-family operation over two constant sets.
- Parameters:
val1 (Any) – The list value being tested.
ops (Any) – The parsed set comparison operators.
val2 (Any) – The filter values.
has_type (str) – The HAS-family operator.
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
- Returns:
A constant expression representing the set result.
- Raises:
FilterTranslationError – If
has_typeis not supported.- Return type:
- httk.store.query.optimade_filters.translate_filter_ast(node, search_variable, property_fulltypes, handlers, recognized_prefixes, *, relationship_targets=(), related_property_resolver=None)[source]¶
Translate one filter syntax-tree node into a search expression.
nodeis aFilterAstnode (as produced byhttk.core.optimade.parse_optimade_filter());search_variableis the backend search variable the expression is built against;property_fulltypes,handlers, andrecognized_prefixesdrive the translation as described in the module docstring.Returns the translated expression, ready to hand to
add().NOTtranslates to the backend’s~; a backend whose set predicates need a second (post-filter) evaluation position derives that from the expression itself, so the caller never has to.Relationship filtering: an identifier dotted with a name in
relationship_targets(e.g.('Identifier', 'references', 'doi')) filters on the properties of related entries.<type>.id HAS ...is served directly by the'<type>.id'handler-table entry. Every other depth-1 dotted filter — comparisons (including<type>.id = ...), string matching,IS KNOWN/IS UNKNOWN, and the HAS family over related list properties — is resolved by a two-phase semi-join: the<type>.prefix is stripped from the node, the resulting sub-filter is passed torelated_property_resolver(without any surroundingNOT— inversion applies to the resulting id-set membership), and the returned ids are substituted back as<type>.id HAS ANY <ids>(an empty id set translates to a constant-false expression). Each dotted node is resolved independently:references.doi CONTAINS "x" AND references.year >= 2000matches entries where some related reference matches the doi condition and some — possibly different — related reference matches the year condition. Without a resolver, dotted filters other than<type>.id HAS ...are not implemented; nested (deeper than depth-1) paths and dottedLENGTHfilters are never supported.- Parameters:
node (httk.core.optimade.FilterAst) – The parsed OPTIMADE filter AST node.
search_variable (httk.store.query.SearchVariable) – The backend search variable receiving the expression.
property_fulltypes (collections.abc.Mapping[str, str]) – Fulltypes keyed by recognized property name.
handlers (HandlerTable) – Property-specific translation handlers.
recognized_prefixes (tuple[str, ...]) – Prefixes whose unknown properties are errors.
relationship_targets (tuple[str, ...]) – Related entry types that support dotted filters.
related_property_resolver (RelatedPropertyResolver | None) – Optional resolver for related-property filters.
- Returns:
The translated backend search expression.
- Raises:
FilterTranslationError – If the filter cannot be translated; see
FilterTranslationErrorfor the failure categories.- Return type:
- httk.store.query.optimade_filters.simple_property_handlers(entry_type, property_keys, property_fulltypes)[source]¶
Build a filter handler table for an entry type from a property-key map.
Provides default handlers for standard
id(matched against theID_FIELDfield) andtype(a constant equal toentry_type). Entries inproperty_keysreplace those defaults when their names overlap. For every property named inproperty_keys(which maps property names to backend field names), handlers are generated from the property’s fulltype inproperty_fulltypes(default"string"): string properties get comparison and stringmatching handlers; integer and float properties get a numeric comparison handler;list of ...properties get a HAS (set membership) handler. Every generated property also gets aknownunknown handler.- Parameters:
entry_type (str) – The served entry type used by the constant
typehandler.property_keys (collections.abc.Mapping[str, str]) – Mapping from served property names to backend field names.
property_fulltypes (collections.abc.Mapping[str, str]) – Fulltypes keyed by served property name.
- Returns:
A handler table keyed by served property name.
- Return type:
dict[str, collections.abc.Mapping[str, collections.abc.Callable[…, Any]]]
- httk.store.query.optimade_filters.relationship_id_handler(rel_key)[source]¶
A
'<type>.id'handler-table entry matching related ids over a list-valued field.rel_keynames a list-valued backend field holding the related entry ids; the returned{'HAS': ...}mapping serves<type>.id HAS ...filters (and the semi-join rewrites of other dotted filters) with the standard set-operation semantics ofset_handler().- Parameters:
rel_key (str) – The backend field name for related entry identifiers.
- Returns:
A handler mapping containing the
HASoperation.- Return type:
collections.abc.Mapping[str, collections.abc.Callable[…, Any]]
- httk.store.query.optimade_filters.filter_searcher(store, target, filter_string, *, entry_type, property_fulltypes, property_keys=None, handlers=None, recognized_prefixes=(), relationship_targets=(), related_property_resolver=None)[source]¶
Build a
Searcheroverstoreapplying an OPTIMADE filter.filter_stringis an OPTIMADE filter string (parsed withhttk.core.optimade.parse_optimade_filter()) or an already-parsedFilterAst. The searcher binds one search variable totarget(the store-specific query target, declared as the searcher output namedentry_type) and applies the translated filter. Whenhandlersis not supplied, a default table is built withsimple_property_handlers()fromproperty_keys(or, whenproperty_keysis also None, from an identity map overproperty_fulltypes). The remaining keyword arguments are passed through totranslate_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, ...]) – Prefixes whose unknown properties are errors.
relationship_targets (tuple[str, ...]) – 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:
FilterTranslationError – If the filter cannot be translated.
httk.core.optimade.ParserSyntaxError – If a filter string does not parse.
- Return type: