Skip to content

links

JsonLinkType = Union[AnyUrl, Link] module-attribute

__all__ = ('LinksResourceAttributes', 'LinksResource') module-attribute

Aggregate

Bases: Enum

Enumeration of aggregate values

Source code in optimade/models/links.py
25
26
27
28
29
30
31
class Aggregate(Enum):
    """Enumeration of aggregate values"""

    OK = "ok"
    TEST = "test"
    STAGING = "staging"
    NO = "no"

NO = 'no' class-attribute instance-attribute

OK = 'ok' class-attribute instance-attribute

STAGING = 'staging' class-attribute instance-attribute

TEST = 'test' class-attribute instance-attribute

Attributes

Bases: BaseModel

Members of the attributes object ("attributes") represent information about the resource object in which it's defined. The keys for Attributes MUST NOT be: relationships links id type

Source code in optimade/models/jsonapi.py
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
class Attributes(BaseModel):
    """
    Members of the attributes object ("attributes\") represent information about the resource object in which it's defined.
    The keys for Attributes MUST NOT be:
        relationships
        links
        id
        type
    """

    model_config = ConfigDict(extra="allow")

    @model_validator(mode="after")
    def check_illegal_attributes_fields(self) -> "Attributes":
        illegal_fields = ("relationships", "links", "id", "type")
        for field in illegal_fields:
            if hasattr(self, field):
                raise ValueError(
                    f"{illegal_fields} MUST NOT be fields under Attributes"
                )
        return self

model_config = ConfigDict(extra='allow') class-attribute instance-attribute

check_illegal_attributes_fields()

Source code in optimade/models/jsonapi.py
329
330
331
332
333
334
335
336
337
@model_validator(mode="after")
def check_illegal_attributes_fields(self) -> "Attributes":
    illegal_fields = ("relationships", "links", "id", "type")
    for field in illegal_fields:
        if hasattr(self, field):
            raise ValueError(
                f"{illegal_fields} MUST NOT be fields under Attributes"
            )
    return self

EntryResource

Bases: Resource

The base model for an entry resource.

Source code in optimade/models/entries.py
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
class EntryResource(Resource):
    """The base model for an entry resource."""

    id: Annotated[
        str,
        OptimadeField(
            description="""An entry's ID as defined in section Definition of Terms.

- **Type**: string.

- **Requirements/Conventions**:
    - **Support**: MUST be supported by all implementations, MUST NOT be `null`.
    - **Query**: MUST be a queryable property with support for all mandatory filter features.
    - **Response**: REQUIRED in the response.

- **Examples**:
    - `"db/1234567"`
    - `"cod/2000000"`
    - `"cod/2000000@1234567"`
    - `"nomad/L1234567890"`
    - `"42"`""",
            support=SupportLevel.MUST,
            queryable=SupportLevel.MUST,
        ),
    ]

    type: Annotated[
        str,
        OptimadeField(
            description="""The name of the type of an entry.

- **Type**: string.

- **Requirements/Conventions**:
    - **Support**: MUST be supported by all implementations, MUST NOT be `null`.
    - **Query**: MUST be a queryable property with support for all mandatory filter features.
    - **Response**: REQUIRED in the response.
    - MUST be an existing entry type.
    - The entry of type `<type>` and ID `<id>` MUST be returned in response to a request for `/<type>/<id>` under the versioned base URL.

- **Example**: `"structures"`""",
            support=SupportLevel.MUST,
            queryable=SupportLevel.MUST,
        ),
    ]

    attributes: Annotated[
        EntryResourceAttributes,
        StrictField(
            description="""A dictionary, containing key-value pairs representing the entry's properties, except for `type` and `id`.
Database-provider-specific properties need to include the database-provider-specific prefix (see section on Database-Provider-Specific Namespace Prefixes).""",
        ),
    ]

    relationships: Annotated[
        Optional[EntryRelationships],
        StrictField(
            description="""A dictionary containing references to other entries according to the description in section Relationships encoded as [JSON API Relationships](https://jsonapi.org/format/1.0/#document-resource-object-relationships).
The OPTIONAL human-readable description of the relationship MAY be provided in the `description` field inside the `meta` dictionary of the JSON API resource identifier object.""",
        ),
    ] = None

attributes: Annotated[EntryResourceAttributes, StrictField(description="A dictionary, containing key-value pairs representing the entry's properties, except for `type` and `id`.\nDatabase-provider-specific properties need to include the database-provider-specific prefix (see section on Database-Provider-Specific Namespace Prefixes).")] instance-attribute

id: Annotated[str, OptimadeField(description='An entry\'s ID as defined in section Definition of Terms.\n\n- **Type**: string.\n\n- **Requirements/Conventions**:\n - **Support**: MUST be supported by all implementations, MUST NOT be `null`.\n - **Query**: MUST be a queryable property with support for all mandatory filter features.\n - **Response**: REQUIRED in the response.\n\n- **Examples**:\n - `"db/1234567"`\n - `"cod/2000000"`\n - `"cod/2000000@1234567"`\n - `"nomad/L1234567890"`\n - `"42"`', support=SupportLevel.MUST, queryable=SupportLevel.MUST)] instance-attribute

meta: Annotated[Optional[Meta], StrictField(description='a meta object containing non-standard meta-information about a resource that can not be represented as an attribute or relationship.')] = None class-attribute instance-attribute

model_config = ConfigDict(json_schema_extra=resource_json_schema_extra) class-attribute instance-attribute

relationships: Annotated[Optional[EntryRelationships], StrictField(description='A dictionary containing references to other entries according to the description in section Relationships encoded as [JSON API Relationships](https://jsonapi.org/format/1.0/#document-resource-object-relationships).\nThe OPTIONAL human-readable description of the relationship MAY be provided in the `description` field inside the `meta` dictionary of the JSON API resource identifier object.')] = None class-attribute instance-attribute

type: Annotated[str, OptimadeField(description='The name of the type of an entry.\n\n- **Type**: string.\n\n- **Requirements/Conventions**:\n - **Support**: MUST be supported by all implementations, MUST NOT be `null`.\n - **Query**: MUST be a queryable property with support for all mandatory filter features.\n - **Response**: REQUIRED in the response.\n - MUST be an existing entry type.\n - The entry of type `<type>` and ID `<id>` MUST be returned in response to a request for `/<type>/<id>` under the versioned base URL.\n\n- **Example**: `"structures"`', support=SupportLevel.MUST, queryable=SupportLevel.MUST)] instance-attribute

LinkType

Bases: Enum

Enumeration of link_type values

Source code in optimade/models/links.py
16
17
18
19
20
21
22
class LinkType(Enum):
    """Enumeration of link_type values"""

    CHILD = "child"
    ROOT = "root"
    EXTERNAL = "external"
    PROVIDERS = "providers"

CHILD = 'child' class-attribute instance-attribute

EXTERNAL = 'external' class-attribute instance-attribute

PROVIDERS = 'providers' class-attribute instance-attribute

ROOT = 'root' class-attribute instance-attribute

LinksResource

Bases: EntryResource

A Links endpoint resource object

Source code in optimade/models/links.py
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
class LinksResource(EntryResource):
    """A Links endpoint resource object"""

    type: Annotated[
        Literal["links"],
        StrictField(
            description="These objects are described in detail in the section Links Endpoint",
            pattern="^links$",
        ),
    ] = "links"

    attributes: Annotated[
        LinksResourceAttributes,
        StrictField(
            description="A dictionary containing key-value pairs representing the Links resource's properties.",
        ),
    ]

    @model_validator(mode="after")
    def relationships_must_not_be_present(self) -> "LinksResource":
        if self.relationships or "relationships" in self.model_fields_set:
            raise ValueError('"relationships" is not allowed for links resources')
        return self

attributes: Annotated[LinksResourceAttributes, StrictField(description="A dictionary containing key-value pairs representing the Links resource's properties.")] instance-attribute

id: Annotated[str, OptimadeField(description='An entry\'s ID as defined in section Definition of Terms.\n\n- **Type**: string.\n\n- **Requirements/Conventions**:\n - **Support**: MUST be supported by all implementations, MUST NOT be `null`.\n - **Query**: MUST be a queryable property with support for all mandatory filter features.\n - **Response**: REQUIRED in the response.\n\n- **Examples**:\n - `"db/1234567"`\n - `"cod/2000000"`\n - `"cod/2000000@1234567"`\n - `"nomad/L1234567890"`\n - `"42"`', support=SupportLevel.MUST, queryable=SupportLevel.MUST)] instance-attribute

meta: Annotated[Optional[Meta], StrictField(description='a meta object containing non-standard meta-information about a resource that can not be represented as an attribute or relationship.')] = None class-attribute instance-attribute

model_config = ConfigDict(json_schema_extra=resource_json_schema_extra) class-attribute instance-attribute

relationships: Annotated[Optional[EntryRelationships], StrictField(description='A dictionary containing references to other entries according to the description in section Relationships encoded as [JSON API Relationships](https://jsonapi.org/format/1.0/#document-resource-object-relationships).\nThe OPTIONAL human-readable description of the relationship MAY be provided in the `description` field inside the `meta` dictionary of the JSON API resource identifier object.')] = None class-attribute instance-attribute

type: Annotated[Literal['links'], StrictField(description='These objects are described in detail in the section Links Endpoint', pattern='^links$')] = 'links' class-attribute instance-attribute

relationships_must_not_be_present()

Source code in optimade/models/links.py
116
117
118
119
120
@model_validator(mode="after")
def relationships_must_not_be_present(self) -> "LinksResource":
    if self.relationships or "relationships" in self.model_fields_set:
        raise ValueError('"relationships" is not allowed for links resources')
    return self

LinksResourceAttributes

Bases: Attributes

Links endpoint resource object attributes

Source code in optimade/models/links.py
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
class LinksResourceAttributes(Attributes):
    """Links endpoint resource object attributes"""

    name: Annotated[
        str,
        StrictField(
            description="Human-readable name for the OPTIMADE API implementation, e.g., for use in clients to show the name to the end-user.",
        ),
    ]
    description: Annotated[
        str,
        StrictField(
            description="Human-readable description for the OPTIMADE API implementation, e.g., for use in clients to show a description to the end-user.",
        ),
    ]
    base_url: Annotated[
        Optional[JsonLinkType],
        StrictField(
            description="JSON API links object, pointing to the base URL for this implementation",
        ),
    ]

    homepage: Annotated[
        Optional[JsonLinkType],
        StrictField(
            description="JSON API links object, pointing to a homepage URL for this implementation",
        ),
    ]

    link_type: Annotated[
        LinkType,
        StrictField(
            title="Link Type",
            description="""The type of the linked relation.
MUST be one of these values: 'child', 'root', 'external', 'providers'.""",
        ),
    ]

    aggregate: Annotated[
        Optional[Aggregate],
        StrictField(
            title="Aggregate",
            description="""A string indicating whether a client that is following links to aggregate results from different OPTIMADE implementations should follow this link or not.
This flag SHOULD NOT be indicated for links where `link_type` is not `child`.

If not specified, clients MAY assume that the value is `ok`.
If specified, and the value is anything different than `ok`, the client MUST assume that the server is suggesting not to follow the link during aggregation by default (also if the value is not among the known ones, in case a future specification adds new accepted values).

Specific values indicate the reason why the server is providing the suggestion.
A client MAY follow the link anyway if it has reason to do so (e.g., if the client is looking for all test databases, it MAY follow the links marked with `aggregate`=`test`).

If specified, it MUST be one of the values listed in section Link Aggregate Options.""",
        ),
    ] = Aggregate.OK

    no_aggregate_reason: Annotated[
        Optional[str],
        StrictField(
            description="""An OPTIONAL human-readable string indicating the reason for suggesting not to aggregate results following the link.
It SHOULD NOT be present if `aggregate`=`ok`.""",
        ),
    ] = None

aggregate: Annotated[Optional[Aggregate], StrictField(title=Aggregate, description='A string indicating whether a client that is following links to aggregate results from different OPTIMADE implementations should follow this link or not.\nThis flag SHOULD NOT be indicated for links where `link_type` is not `child`.\n\nIf not specified, clients MAY assume that the value is `ok`.\nIf specified, and the value is anything different than `ok`, the client MUST assume that the server is suggesting not to follow the link during aggregation by default (also if the value is not among the known ones, in case a future specification adds new accepted values).\n\nSpecific values indicate the reason why the server is providing the suggestion.\nA client MAY follow the link anyway if it has reason to do so (e.g., if the client is looking for all test databases, it MAY follow the links marked with `aggregate`=`test`).\n\nIf specified, it MUST be one of the values listed in section Link Aggregate Options.')] = Aggregate.OK class-attribute instance-attribute

base_url: Annotated[Optional[JsonLinkType], StrictField(description='JSON API links object, pointing to the base URL for this implementation')] instance-attribute

description: Annotated[str, StrictField(description='Human-readable description for the OPTIMADE API implementation, e.g., for use in clients to show a description to the end-user.')] instance-attribute

homepage: Annotated[Optional[JsonLinkType], StrictField(description='JSON API links object, pointing to a homepage URL for this implementation')] instance-attribute

model_config = ConfigDict(extra='allow') class-attribute instance-attribute

name: Annotated[str, StrictField(description='Human-readable name for the OPTIMADE API implementation, e.g., for use in clients to show the name to the end-user.')] instance-attribute

no_aggregate_reason: Annotated[Optional[str], StrictField(description='An OPTIONAL human-readable string indicating the reason for suggesting not to aggregate results following the link.\nIt SHOULD NOT be present if `aggregate`=`ok`.')] = None class-attribute instance-attribute

check_illegal_attributes_fields()

Source code in optimade/models/jsonapi.py
329
330
331
332
333
334
335
336
337
@model_validator(mode="after")
def check_illegal_attributes_fields(self) -> "Attributes":
    illegal_fields = ("relationships", "links", "id", "type")
    for field in illegal_fields:
        if hasattr(self, field):
            raise ValueError(
                f"{illegal_fields} MUST NOT be fields under Attributes"
            )
    return self

StrictField(default=PydanticUndefined, *, 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
default Any

The only non-keyword argument allowed for Field.

PydanticUndefined
description Optional[str]

The description of the Field; if this is not specified then a UserWarning will be emitted.

None
**kwargs Any

Extra keyword arguments to be passed to Field.

{}

Raises:

Type Description
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:

Type Description
Any

The pydantic Field.

Source code in optimade/models/utils.py
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
def StrictField(
    default: "Any" = PydanticUndefined,
    *,
    description: Optional[str] = None,
    **kwargs: "Any",
) -> Any:
    """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:
        default: The only non-keyword argument allowed for 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_schema_and_field_keys = ["pattern"]

    allowed_keys = [
        "pattern",
        "uniqueItems",
    ] + OPTIMADE_SCHEMA_EXTENSION_KEYS
    _banned = [k for k in kwargs if k not in set(_PYDANTIC_FIELD_KWARGS + allowed_keys)]

    if _banned:
        raise RuntimeError(
            f"Not creating StrictField({default!r}, **{kwargs!r}) with "
            f"forbidden keywords {_banned}."
        )

    # Handle description
    if description is None:
        warnings.warn(
            f"No description provided for StrictField specified by {default!r}, "
            f"**{kwargs!r}."
        )
    else:
        kwargs["description"] = description

    # OPTIMADE schema extensions
    json_schema_extra: dict[str, Any] = kwargs.pop("json_schema_extra", {})

    # Go through all JSON Schema keys and add them to the json_schema_extra.
    for key in allowed_keys:
        if key not in kwargs:
            continue

        # If they are OPTIMADE schema extensions, add them with the OPTIMADE prefix.
        schema_key = (
            f"{OPTIMADE_SCHEMA_EXTENSION_PREFIX}{key}"
            if key in OPTIMADE_SCHEMA_EXTENSION_KEYS
            else key
        )

        for key_variant in (key, schema_key):
            if key_variant in json_schema_extra:
                if json_schema_extra.pop(key_variant) != kwargs[key]:
                    raise RuntimeError(
                        f"Conflicting values for {key} in json_schema_extra and kwargs."
                    )

        json_schema_extra[schema_key] = (
            kwargs[key] if key in allowed_schema_and_field_keys else kwargs.pop(key)
        )

    kwargs["json_schema_extra"] = json_schema_extra

    return Field(default, **kwargs)