queries¶
Pydantic models/schemas for the Queries resource.
QUERY_PARAMETERS
¶
Entry listing URL query parameters from the optimade
package
(EntryListingQueryParams
).
EndpointEntryType (Enum)
¶
EntryResource (EntryResource)
pydantic-model
¶
Entry Resource ensuring datetimes are not naive.
ensure_non_naive_datetime(value)
classmethod
¶
Set timezone to UTC if datetime is naive.
Source code in optimade_gateway/models/queries.py
@validator("attributes")
def ensure_non_naive_datetime(
cls, value: EntryResourceAttributes
) -> EntryResourceAttributes:
"""Set timezone to UTC if datetime is naive."""
if value.last_modified and value.last_modified.tzinfo is None:
value.last_modified = value.last_modified.replace(tzinfo=timezone.utc)
return value
GatewayQueryResponse (Response)
pydantic-model
¶
Response from a Gateway Query.
__init__(self, **data)
special
¶
Remove root_validator either_data_meta_or_errors_must_be_set
.
Source code in optimade_gateway/models/queries.py
def __init__(self, **data: Any) -> None:
"""Remove root_validator `either_data_meta_or_errors_must_be_set`."""
self._remove_pre_root_validators()
super().__init__(**data)
OptimadeQueryParameters (BaseModel)
pydantic-model
¶
Common OPTIMADE entry listing endpoint query parameters.
email_address: EmailStr
pydantic-field
¶
An email address of the user making the request.
The email SHOULD be that of a person and not an automatic system.
Example: http://example.com/v1/structures?email_address=user@example.com
filter: str
pydantic-field
¶
A filter string, in the format described in section API Filtering Format Specification of the specification.
include: str
pydantic-field
¶
A server MAY implement the JSON API concept of returning compound documents by utilizing the include
query parameter as specified by JSON API 1.0.
All related resource objects MUST be returned as part of an array value for the top-level included
field, see the section JSON Response Schema: Common Fields.
The value of include
MUST be a comma-separated list of "relationship paths", as defined in the JSON API.
If relationship paths are not supported, or a server is unable to identify a relationship path a 400 Bad Request
response MUST be made.
The default value for include
is references
.
This means references
entries MUST always be included under the top-level field included
as default, since a server assumes if include
is not specified by a client in the request, it is still specified as include=references
.
Note, if a client explicitly specifies include
and leaves out references
, references
resource objects MUST NOT be included under the top-level field included
, as per the definition of included
, see section JSON Response Schema: Common Fields.
Note: A query with the parameter
include
set to the empty string means no related resource objects are to be returned under the top-level fieldincluded
.
page_above: ConstrainedIntValue
pydantic-field
¶
RECOMMENDED for use with value-based pagination: using page_above
/page_below
and page_limit
is RECOMMENDED.
Example: Fetch up to 100 structures above sort-field value 4000 (in this example, server chooses to fetch results sorted by increasing id
, so page_above
value refers to an id
value): /structures?page_above=4000&page_limit=100
.
page_below: ConstrainedIntValue
pydantic-field
¶
RECOMMENDED for use with value-based pagination: using page_above
/page_below
and page_limit
is RECOMMENDED.
page_cursor: ConstrainedIntValue
pydantic-field
¶
RECOMMENDED for use with cursor-based pagination: using page_cursor
and page_limit
is RECOMMENDED.
page_limit: ConstrainedIntValue
pydantic-field
¶
Sets a numerical limit on the number of entries returned.
See JSON API 1.0.
The API implementation MUST return no more than the number specified.
It MAY return fewer.
The database MAY have a maximum limit and not accept larger numbers (in which case an error code -- 403 Forbidden -- MUST be returned).
The default limit value is up to the API implementation to decide.
Example: http://example.com/optimade/v1/structures?page_limit=100
page_number: ConstrainedIntValue
pydantic-field
¶
RECOMMENDED for use with page-based pagination: using page_number
and page_limit
is RECOMMENDED.
It is RECOMMENDED that the first page has number 1, i.e., that page_number
is 1-based.
Example: Fetch page 2 of up to 50 structures per page: /structures?page_number=2&page_limit=50
.
page_offset: ConstrainedIntValue
pydantic-field
¶
RECOMMENDED for use with offset-based pagination: using page_offset
and page_limit
is RECOMMENDED.
Example: Skip 50 structures and fetch up to 100: /structures?page_offset=50&page_limit=100
.
response_fields: ConstrainedStrValue
pydantic-field
¶
A comma-delimited set of fields to be provided in the output.
If provided, these fields MUST be returned along with the REQUIRED fields.
Other OPTIONAL fields MUST NOT be returned when this parameter is present.
Example: http://example.com/v1/structures?response_fields=last_modified,nsites
response_format: str
pydantic-field
¶
The output format requested (see section Response Format).
Defaults to the format string 'json', which specifies the standard output format described in this specification.
Example: http://example.com/v1/structures?response_format=xml
sort: ConstrainedStrValue
pydantic-field
¶
If supporting sortable queries, an implementation MUST use the sort
query parameter with format as specified by JSON API 1.0.
An implementation MAY support multiple sort fields for a single query. If it does, it again MUST conform to the JSON API 1.0 specification.
If an implementation supports sorting for an entry listing endpoint, then the /info/<entries>
endpoint MUST include, for each field name <fieldname>
in its data.properties.<fieldname>
response value that can be used for sorting, the key sortable
with value true
.
If a field name under an entry listing endpoint supporting sorting cannot be used for sorting, the server MUST either leave out the sortable
key or set it equal to false
for the specific field name.
The set of field names, with sortable
equal to true
are allowed to be used in the "sort fields" list according to its definition in the JSON API 1.0 specification.
The field sortable
is in addition to each property description and other OPTIONAL fields.
An example is shown in the section Entry Listing Info Endpoints.
QueryCreate (EntryResourceCreate, QueryResourceAttributes)
pydantic-model
¶
Model for creating new Query resources in the MongoDB
sort_not_supported(value)
classmethod
¶
Warn and reset value if sort
is supplied.
Source code in optimade_gateway/models/queries.py
@validator("query_parameters")
def sort_not_supported(
cls, value: OptimadeQueryParameters
) -> OptimadeQueryParameters:
"""Warn and reset value if `sort` is supplied."""
if value.sort:
warnings.warn(SortNotSupported())
value.sort = None
return value
QueryResource (EntryResource)
pydantic-model
¶
OPTIMADE query resource for a gateway
response_as_optimade(self, url=None)
async
¶
Return attributes.response
as a valid OPTIMADE entry listing response.
Note, this method disregards the state of the query and will simply return the query results as they currently are (if there are any at all).
Parameters:
Name | Type | Description | Default |
---|---|---|---|
url |
Union[urllib.parse.ParseResult, urllib.parse.SplitResult, starlette.datastructures.URL, str] |
Optionally, update the |
None |
Returns:
Type | Description |
---|---|
A valid OPTIMADE entry-listing response according to the
[OPTIMADE specification](https |
//github.com/Materials-Consortia/OPTIMADE/blob/master/optimade.rst#entry-listing-endpoints) or an error response, if errors were returned or occurred during the query. |
Source code in optimade_gateway/models/queries.py
async def response_as_optimade(
self,
url: Optional[
Union[urllib.parse.ParseResult, urllib.parse.SplitResult, StarletteURL, str]
] = None,
) -> Union[EntryResponseMany, ErrorResponse]:
"""Return `attributes.response` as a valid OPTIMADE entry listing response.
Note, this method disregards the state of the query and will simply return the
query results as they currently are (if there are any at all).
Parameters:
url: Optionally, update the `meta.query.representation` value with this.
Returns:
A valid OPTIMADE entry-listing response according to the
[OPTIMADE specification](https://github.com/Materials-Consortia/OPTIMADE/blob/master/optimade.rst#entry-listing-endpoints)
or an error response, if errors were returned or occurred during the query.
"""
from optimade.server.routers.utils import ( # pylint: disable=import-outside-toplevel
meta_values,
)
async def _update_id(
entry_: Union[EntryResource, Dict[str, Any]], database_provider_: str
) -> Union[EntryResource, Dict[str, Any]]:
"""Internal utility function to prepend the entries' `id` with
`provider/database/`.
Parameters:
entry_: The entry as a model or a dictionary.
database_provider_: `provider/database` string.
Returns:
The entry with an updated `id` value.
"""
if isinstance(entry_, dict):
_entry = deepcopy(entry_)
_entry["id"] = f"{database_provider_}/{entry_['id']}"
else:
_entry = entry_.copy(deep=True)
_entry.id = f"{database_provider_}/{entry_.id}" # type: ignore[union-attr]
return _entry
if not self.attributes.response:
# The query has not yet been initiated
return ErrorResponse(
errors=[
{
"detail": (
"Can not return as a valid OPTIMADE response as the query has"
" not yet been initialized."
),
"id": "OPTIMADE_GATEWAY_QUERY_NOT_INITIALIZED",
}
],
meta=meta_values(
url=url or f"/queries/{self.id}?",
data_returned=0,
data_available=0,
more_data_available=False,
),
)
meta_ = self.attributes.response.meta
if url:
meta_ = meta_.dict(exclude_unset=True)
for repeated_key in (
"query",
"api_version",
"time_stamp",
"provider",
"implementation",
):
meta_.pop(repeated_key, None)
meta_ = meta_values(url=url, **meta_)
# Error response
if self.attributes.response.errors:
return ErrorResponse(
errors=self.attributes.response.errors,
meta=meta_,
)
# Data response
results = []
for database_provider, entries in self.attributes.response.data.items():
results.extend(
[await _update_id(entry, database_provider) for entry in entries]
)
return self.attributes.endpoint.get_response_model()(
data=results,
meta=meta_,
links=self.attributes.response.links,
)
QueryResourceAttributes (EntryResourceAttributes)
pydantic-model
¶
Attributes for an OPTIMADE gateway query.
endpoint: EndpointEntryType
pydantic-field
¶
The entry endpoint queried, e.g., 'structures'.
gateway_id: str
pydantic-field
required
¶
The OPTIMADE gateway ID for this query.
query_parameters: OptimadeQueryParameters
pydantic-field
required
¶
OPTIMADE query parameters for entry listing endpoints used for this query.
response: GatewayQueryResponse
pydantic-field
¶
Response from gateway query.
state: QueryState
pydantic-field
¶
Current state of Gateway Query.
only_allow_structures(value)
classmethod
¶
Temporarily only allow queries to "structures" endpoints.
Source code in optimade_gateway/models/queries.py
@validator("endpoint")
def only_allow_structures(cls, value: EndpointEntryType) -> EndpointEntryType:
"""Temporarily only allow queries to "structures" endpoints."""
if value != EndpointEntryType.STRUCTURES:
raise NotImplementedError(
'OPTIMADE Gateway temporarily only supports queries to "structures" '
'endpoints, i.e.: endpoint="structures"'
)
return value