prepare¶
get_query_params(query_parameters, database_id, filter_mapping)
async
¶
Construct the parsed URL query parameters
Source code in optimade_gateway/queries/prepare.py
async def get_query_params(
query_parameters: OptimadeQueryParameters,
database_id: str,
filter_mapping: Dict[str, Union[str, None]],
) -> str:
"""Construct the parsed URL query parameters"""
query_params = {
param: value for param, value in query_parameters.dict().items() if value
}
if filter_mapping[database_id]:
query_params.update({"filter": filter_mapping[database_id]})
return urllib.parse.urlencode(query_params)
get_response_model(endpoint_model)
async
¶
Import and return response model based on endpoint_model
.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
endpoint_model | Tuple[str, str] | The | required |
Returns:
Type | Description |
---|---|
Union[optimade.models.responses.EntryResponseMany, optimade.models.responses.EntryResponseOne] | The imported response model class, e.g., |
Source code in optimade_gateway/queries/prepare.py
async def get_response_model(
endpoint_model: Tuple[str, str]
) -> Union[EntryResponseMany, EntryResponseOne]:
"""Import and return response model based on `endpoint_model`.
Parameters:
endpoint_model: The
[`endpoint_model`][optimade_gateway.models.queries.QueryResourceAttributes.endpoint_model]
from the
[`QueryResource` attributes][optimade_gateway.models.queries.QueryResourceAttributes].
Returns:
The imported response model class, e.g., `StructureResponseMany`.
"""
module, name = endpoint_model
return getattr(importlib.import_module(module), name)
prepare_query(database_ids, endpoint_model, filter_query)
async
¶
Prepare a query by returning necessary variables.
Source code in optimade_gateway/queries/prepare.py
async def prepare_query(
database_ids: List[str],
endpoint_model: Tuple[str, str],
filter_query: Union[str, None],
) -> Tuple[Dict[str, Union[str, None]], Union[EntryResponseMany, EntryResponseOne]]:
"""Prepare a query by returning necessary variables."""
return (
await update_query_filter(database_ids, filter_query),
await get_response_model(endpoint_model),
)
update_query_filter(database_ids, filter_query)
async
¶
Update the query parameter filter
value to be database-specific
This is needed due to the served change of id
values. If someone searches for a gateway-changed id
, it needs to be reverted to be database-specific.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
database_ids | List[str] | List of the databases to create updated filter values for. These values are part of the gateway-changed | required |
filter_query | Optional[str] | The submitted | required |
Returns:
Type | Description |
---|---|
Dict[str, Optional[str]] | A mapping for database IDs to database-specific |
Source code in optimade_gateway/queries/prepare.py
async def update_query_filter(
database_ids: List[str], filter_query: Union[str, None]
) -> Dict[str, Union[str, None]]:
"""Update the query parameter `filter` value to be database-specific
This is needed due to the served change of `id` values.
If someone searches for a gateway-changed `id`, it needs to be reverted to be
database-specific.
Parameters:
database_ids: List of the databases to create updated filter values for.
These values are part of the gateway-changed `id` values and are essential.
filter_query: The submitted `filter` query parameter value. Can be `None` if not supplied.
Returns:
A mapping for database IDs to database-specific `filter` query parameter values.
"""
updated_filter = {}.fromkeys(database_ids, filter_query)
if not filter_query:
return updated_filter
for id_match in re.finditer(
r'"(?P<id_value_l>[^\s]*)"[\s]*(<|>|<=|>=|=|!=|CONTAINS|STARTS WITH|ENDS WITH|STARTS|ENDS)'
r'[\s]*id|[^_]+id[\s]*(<|>|<=|>=|=|!=|CONTAINS|STARTS WITH|ENDS WITH|STARTS|ENDS)[\s]*"'
r'(?P<id_value_r>[^\s]*)"',
f"={filter_query}" if filter_query else "",
):
matched_id = id_match.group("id_value_l") or id_match.group("id_value_r")
for database_id in database_ids:
if matched_id.startswith(f"{database_id}/"):
# Database found
updated_filter[database_id] = updated_filter[database_id].replace(
f"{database_id}/", "", 1
)
break
# TODO: Remove `id="value"` sections here for queries to databases that doesn't match the id value!
else:
raise BadRequest(
detail=(
f"Structures entry <id={matched_id}> not found. To get a specific structures "
"entry one needs to prepend the ID with a database ID belonging to the gateway,"
f" e.g., '{database_ids[0]}/<local_database_ID>'. Available"
f"databases for this gateway: {database_ids}"
)
)
return updated_filter