def get_info_entry(request: Request, entry: str): from optimade.models import EntryInfoResource valid_entry_info_endpoints = ENTRY_INFO_SCHEMAS.keys() if entry not in valid_entry_info_endpoints: raise HTTPException( status_code=404, detail= f"Entry info not found for {entry}, valid entry info endpoints are:" f" {valid_entry_info_endpoints}", ) schema = ENTRY_INFO_SCHEMAS[entry]() queryable_properties = {"id", "type", "attributes"} properties, _ = retrieve_queryable_properties(schema, queryable_properties) output_fields_by_format = {"json": list(properties.keys())} return EntryInfoResponse( meta=meta_values(str(request.url), 1, 1, more_data_available=False), data=EntryInfoResource( formats=list(output_fields_by_format.keys()), description=schema.get( "description", "Endpoint to represent AiiDA Nodes in the OPTiMaDe format", ), properties=properties, output_fields_by_format=output_fields_by_format, ), )
def _parse_params(self, params: EntryListingQueryParams) -> dict: """Parse query parameters and transform them into AiiDA QueryBuilder concepts""" cursor_kwargs = {} # filter if getattr(params, "filter", False): aiida_filter = self.transformer.transform( self.parser.parse(params.filter)) self._filter_fields = set() cursor_kwargs["filters"] = self._alias_filter(aiida_filter) # response_format if (getattr(params, "response_format", False) and params.response_format != "json"): raise HTTPException(status_code=400, detail="Only 'json' response_format supported") # page_limit if getattr(params, "page_limit", False): limit = self.page_limit if params.page_limit != self.page_limit: limit = params.page_limit if limit > self.db_page_limit: raise HTTPException( status_code=403, detail= f"Max allowed page_limit is {self.db_page_limit}, you requested {limit}", ) if limit == 0: limit = self.page_limit cursor_kwargs["limit"] = limit # response_fields # All OPTiMaDe fields fields = {"id", "type"} fields |= self.get_attribute_fields() # All provider-specific fields fields |= {self.provider + _ for _ in self.provider_fields} cursor_kwargs["fields"] = fields cursor_kwargs["project"] = list( {self.resource_mapper.alias_for(f) for f in fields}) # sort # NOTE: sorting only works for extras fields for the nodes already with calculated extras. # To calculate all extras, make a single filter query using any extra field. if getattr(params, "sort", False): sort_spec = [] for entity_property in params.sort.split(","): field = entity_property sort_direction = "asc" if entity_property.startswith("-"): field = field[1:] sort_direction = "desc" aliased_field = self.resource_mapper.alias_for(field) _, properties = retrieve_queryable_properties( self.resource_cls.schema(), {"id", "type", "attributes"}) field_type = properties[field].get( "format", properties[field].get("type", "")) if field_type == "array": raise TypeError( "Cannot sort on a field with a list value type") sort_spec.append({ aliased_field: { "order": sort_direction, "cast": self.CAST_MAPPING[field_type], } }) cursor_kwargs["order_by"] = sort_spec # page_offset if getattr(params, "page_offset", False): cursor_kwargs["offset"] = params.page_offset return cursor_kwargs