utils¶
ANONYMOUS_ELEMENTS
¶
Returns the first 150 values of the anonymous element generator.
ATOMIC_NUMBERS
¶
CHEMICAL_FORMULA_REGEXP
¶
CHEMICAL_SYMBOLS
¶
EXTRA_SYMBOLS
¶
SemanticVersion (str)
¶
A custom type for a semantic version, using the recommended semver regexp from https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string.
base_version: str
property
readonly
¶
The base version string without patch and metadata info.
build_metadata: str
property
readonly
¶
The build metadata.
major: int
property
readonly
¶
The major version number.
minor: int
property
readonly
¶
The minor version number.
patch: int
property
readonly
¶
The patch version number.
prerelease: str
property
readonly
¶
The pre-release tag.
regex
¶
__get_validators__()
classmethod
special
¶
Source code in optimade/models/utils.py
@classmethod
def __get_validators__(cls):
yield cls.validate
__modify_schema__(field_schema)
classmethod
special
¶
Source code in optimade/models/utils.py
@classmethod
def __modify_schema__(cls, field_schema):
field_schema.update(
pattern=cls.regex.pattern,
examples=["0.10.1", "1.0.0-rc.2", "1.2.3-rc.5+develop"],
)
validate(v)
classmethod
¶
Source code in optimade/models/utils.py
@classmethod
def validate(cls, v: str):
if not cls.regex.match(v):
raise ValueError(
f"Unable to validate the version string {v!r} as a semantic version (expected <major>.<minor>.<patch>)."
"See https://semver.org/#is-there-a-suggested-regular-expression-regex-to-check-a-semver-string for more information."
)
return v
OptimadeField(*args, *, support=None, queryable=None, unit=None, **kwargs)
¶
A wrapper around pydantic.Field
that adds OPTIMADE-specific field paramters queryable
, support
and unit
, indicating the corresponding support level in the specification and the physical unit of the field.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
support | Optional[optimade.models.utils.SupportLevel] | The support level of the field itself, i.e. whether the field can be null or omitted by an implementation. | None |
queryable | Optional[optimade.models.utils.SupportLevel] | The support level corresponding to the queryablility of this field. | None |
unit | Optional[str] | A string describing the unit of the field. | None |
Returns:
Type | Description |
---|---|
<cyfunction Field at 0x7fc69fa28790> | The pydantic field with extra validation provided by |
Source code in optimade/models/utils.py
def OptimadeField(
*args,
support: Optional[SupportLevel] = None,
queryable: Optional[SupportLevel] = None,
unit: Optional[str] = None,
**kwargs,
) -> Field:
"""A wrapper around `pydantic.Field` that adds OPTIMADE-specific
field paramters `queryable`, `support` and `unit`, indicating
the corresponding support level in the specification and the
physical unit of the field.
Arguments:
support: The support level of the field itself, i.e. whether the field
can be null or omitted by an implementation.
queryable: The support level corresponding to the queryablility
of this field.
unit: A string describing the unit of the field.
Returns:
The pydantic field with extra validation provided by [`StrictField`][optimade.models.utils.StrictField].
"""
# Collect non-null keyword arguments to add to the Field schema
if unit is not None:
kwargs["unit"] = unit
if queryable is not None:
if isinstance(queryable, str):
queryable = SupportLevel(queryable.lower())
kwargs["queryable"] = queryable
if support is not None:
if isinstance(support, str):
support = SupportLevel(support.lower())
kwargs["support"] = support
return StrictField(*args, **kwargs)
StrictField(*args, *, description=None, **kwargs)
¶
A wrapper around pydantic.Field
that does the following:
- Forbids any "extra" keys that would be passed to
pydantic.Field
, except those used elsewhere to modify the schema in-place, e.g. "uniqueItems", "pattern" and those added by OptimadeField, e.g. "unit", "queryable" and "sortable". - Emits a warning when no description is provided.
Parameters:
Name | Type | Description | Default |
---|---|---|---|
*args | Positional arguments passed through to | () | |
description | str | The description of the | None |
**kwargs | Extra keyword arguments to be passed to | {} |
Exceptions:
Type | Description |
---|---|
RuntimeError | If |
Returns:
Type | Description |
---|---|
<cyfunction Field at 0x7fc69fa28790> | The pydantic |
Source code in optimade/models/utils.py
def StrictField(
*args,
description: str = None,
**kwargs,
) -> Field:
"""A wrapper around `pydantic.Field` that does the following:
- Forbids any "extra" keys that would be passed to `pydantic.Field`,
except those used elsewhere to modify the schema in-place,
e.g. "uniqueItems", "pattern" and those added by OptimadeField, e.g.
"unit", "queryable" and "sortable".
- Emits a warning when no description is provided.
Arguments:
*args: Positional arguments passed through to `Field`.
description: The description of the `Field`; if this is not
specified then a `UserWarning` will be emitted.
**kwargs: Extra keyword arguments to be passed to `Field`.
Raises:
RuntimeError: If `**kwargs` contains a key not found in the
function signature of `Field`, or in the extensions used
by models in this package (see above).
Returns:
The pydantic `Field`.
"""
allowed_keys = [
"unit",
"pattern",
"uniqueItems",
"support",
"queryable",
"sortable",
]
_banned = [k for k in kwargs if k not in set(_PYDANTIC_FIELD_KWARGS + allowed_keys)]
if _banned:
raise RuntimeError(
f"Not creating StrictField({args}, {kwargs}) with forbidden keywords {_banned}."
)
if description is not None:
kwargs["description"] = description
if description is None:
warnings.warn(
f"No description provided for StrictField specified by {args}, {kwargs}."
)
return Field(*args, **kwargs)
anonymous_element_generator()
¶
Generator that yields the next symbol in the A, B, Aa, ... Az naming scheme.
Source code in optimade/models/utils.py
def anonymous_element_generator():
"""Generator that yields the next symbol in the A, B, Aa, ... Az naming scheme."""
from string import ascii_lowercase
for size in itertools.count(1):
for s in itertools.product(ascii_lowercase, repeat=size):
s = list(s)
s[0] = s[0].upper()
yield "".join(s)