Skip to content

Commit

Permalink
Add field-specific validator overrides to set certain operators as op…
Browse files Browse the repository at this point in the history
…tional (#1025)
  • Loading branch information
ml-evs committed Dec 20, 2021
1 parent 1b1225b commit 75d2e3e
Show file tree
Hide file tree
Showing 2 changed files with 40 additions and 17 deletions.
50 changes: 33 additions & 17 deletions optimade/validator/config.py
Original file line number Diff line number Diff line change
Expand Up @@ -7,10 +7,16 @@
"""

from typing import Dict, Any, Set, List
from typing import Dict, Any, Set, List, Container
from pydantic import BaseSettings, Field

from optimade.models import InfoResponse, IndexInfoResponse, DataType, StructureFeatures
from optimade.models import (
InfoResponse,
IndexInfoResponse,
DataType,
StructureFeatures,
SupportLevel,
)
from optimade.validator.utils import (
ValidatorLinksResponse,
ValidatorReferenceResponseOne,
Expand Down Expand Up @@ -61,29 +67,19 @@

_UNIQUE_PROPERTIES = ("id", "immutable_id")

inclusive_ops = ("=", "<=", ">=")
substring_operators = ("CONTAINS", "STARTS WITH", "STARTS", "ENDS WITH", "ENDS")

_INCLUSIVE_OPERATORS = {
DataType.STRING: (
"=",
"<=",
">=",
"CONTAINS",
"STARTS WITH",
"STARTS",
"ENDS WITH",
"ENDS",
),
DataType.STRING: inclusive_ops + substring_operators,
DataType.TIMESTAMP: (
# N.B. "=" and "<=" are disabled due to issue with microseconds stored in database vs API response (see Materials-Consortia/optimade-python-tools/#606)
# ">=" is fine as all microsecond trimming will round times down
# "=",
# "<=",
">=",
),
DataType.INTEGER: (
"=",
"<=",
">=",
),
DataType.INTEGER: inclusive_ops,
DataType.FLOAT: (),
DataType.LIST: ("HAS", "HAS ALL", "HAS ANY"),
}
Expand All @@ -99,6 +95,16 @@
}


_FIELD_SPECIFIC_OVERRIDES = {
"chemical_formula_anonymous": {
SupportLevel.OPTIONAL: substring_operators,
},
"chemical_formula_reduced": {
SupportLevel.OPTIONAL: substring_operators,
},
}


class ValidatorConfig(BaseSettings):
"""This class stores validator config parameters in a way that
can be easily modified for testing niche implementations. Many
Expand Down Expand Up @@ -150,6 +156,16 @@ class ValidatorConfig(BaseSettings):
),
)

field_specific_overrides: Dict[str, Dict[SupportLevel, Container[str]]] = Field(
_FIELD_SPECIFIC_OVERRIDES,
description=(
"Some fields do not require all type comparison operators to be supported. "
"This dictionary allows overriding the list of supported operators for a field, using "
"the field name as a key, and the support level of different operators with a subkey. "
"Queries on fields listed in this way will pass the validator provided the server returns a 501 status."
),
)

links_endpoint: str = Field("links", description="The name of the links endpoint")
versions_endpoint: str = Field(
"versions", description="The name of the versions endpoint"
Expand Down
7 changes: 7 additions & 0 deletions optimade/validator/validator.py
Original file line number Diff line number Diff line change
Expand Up @@ -778,11 +778,18 @@ def _construct_single_property_filters(

inclusive_operators = CONF.inclusive_operators[prop_type]
exclusive_operators = CONF.exclusive_operators[prop_type]
field_specific_support_overrides = CONF.field_specific_overrides.get(prop, {})

for operator in inclusive_operators | exclusive_operators:
# Need to pre-format list and string test values for the query
_test_value = self._format_test_value(test_value, prop_type, operator)

query_optional = (
query_optional
or operator
in field_specific_support_overrides.get(SupportLevel.OPTIONAL, [])
)

query = f"{prop} {operator} {_test_value}"
request = f"{endp}?filter={query}"
response, message = self._get_endpoint(
Expand Down

0 comments on commit 75d2e3e

Please sign in to comment.