schemas¶
ENTRY_INFO_SCHEMAS: dict
¶
This dictionary is used to define the /info/<entry_type>
endpoints.
retrieve_queryable_properties(schema, queryable_properties=None, entry_type=None)
¶
Recursively loops through the schema of a pydantic model and resolves all references, returning a dictionary of all the OPTIMADE-queryable properties of that model.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
schema |
dict |
The schema of the pydantic model. |
required |
queryable_properties |
Optional[collections.abc.Iterable[str]] |
The list of properties to find in the schema. |
None |
entry_type |
Optional[str] |
An optional entry type for the model. Will be used to lookup schemas for any config-defined fields. |
None |
Returns:
Type | Description |
---|---|
dict |
A flat dictionary with properties as keys, containing the field description, unit, sortability, support level, queryability and type, where provided. |
Source code in optimade/server/schemas.py
def retrieve_queryable_properties(
schema: dict,
queryable_properties: Optional[Iterable[str]] = None,
entry_type: Optional[str] = None,
) -> dict:
"""Recursively loops through the schema of a pydantic model and
resolves all references, returning a dictionary of all the
OPTIMADE-queryable properties of that model.
Parameters:
schema: The schema of the pydantic model.
queryable_properties: The list of properties to find in the schema.
entry_type: An optional entry type for the model. Will be used to
lookup schemas for any config-defined fields.
Returns:
A flat dictionary with properties as keys, containing the field
description, unit, sortability, support level, queryability
and type, where provided.
"""
properties = {}
for name, value in schema["properties"].items():
if not queryable_properties or name in queryable_properties:
if "$ref" in value:
path = value["$ref"].split("/")[1:]
sub_schema = schema.copy()
while path:
next_key = path.pop(0)
sub_schema = sub_schema[next_key]
sub_queryable_properties = sub_schema["properties"].keys()
properties.update(
retrieve_queryable_properties(sub_schema, sub_queryable_properties)
)
else:
properties[name] = {"description": value.get("description", "")}
# Update schema with extension keys provided they are not None
for key in (
"x-optimade-unit",
"x-optimade-queryable",
"x-optimade-support",
):
if value.get(key) is not None:
properties[name][key.replace("x-optimade-", "")] = value[key]
# All properties are sortable with the MongoDB backend.
# While the result for sorting lists may not be as expected, they are still sorted.
properties[name]["sortable"] = value.get("x-optimade-sortable", True)
# Try to get OpenAPI-specific "format" if possible, else get "type"; a mandatory OpenAPI key.
properties[name]["type"] = DataType.from_json_type(
value.get("format", value.get("type"))
)
# If specified, check the config for any additional well-described provider fields
if entry_type:
from optimade.server.config import CONFIG
described_provider_fields = [
field
for field in CONFIG.provider_fields.get(entry_type, {}) # type: ignore[call-overload]
if isinstance(field, dict)
]
for field in described_provider_fields:
name = (
f"_{CONFIG.provider.prefix}_{field['name']}"
if not field["name"].startswith("_")
else field["name"]
)
properties[name] = {k: field[k] for k in field if k != "name"}
properties[name]["sortable"] = field.get("sortable", True)
return properties