Skip to content

optimade_json

Modified JSON API v1.0 for OPTIMADE API

BaseRelationshipMeta

Bases: Meta

Specific meta field for base relationship resource

Source code in optimade/models/optimade_json.py
404
405
406
407
408
409
410
411
412
class BaseRelationshipMeta(jsonapi.Meta):
    """Specific meta field for base relationship resource"""

    description: Annotated[
        str,
        StrictField(
            description="OPTIONAL human-readable description of the relationship."
        ),
    ]

description: Annotated[str, StrictField(description='OPTIONAL human-readable description of the relationship.')] instance-attribute

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

BaseRelationshipResource

Bases: BaseResource

Minimum requirements to represent a relationship resource

Source code in optimade/models/optimade_json.py
415
416
417
418
419
420
421
422
423
class BaseRelationshipResource(jsonapi.BaseResource):
    """Minimum requirements to represent a relationship resource"""

    meta: Annotated[
        Optional[BaseRelationshipMeta],
        StrictField(
            description="Relationship meta field. MUST contain 'description' if supplied.",
        ),
    ] = None

id: Annotated[str, StrictField(description='Resource ID')] instance-attribute

meta: Annotated[Optional[BaseRelationshipMeta], StrictField(description="Relationship meta field. MUST contain 'description' if supplied.")] = None class-attribute instance-attribute

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

type: Annotated[str, StrictField(description='Resource type')] instance-attribute

DataType

Bases: Enum

Optimade Data types

See the section "Data types" in the OPTIMADE API specification for more information.

Source code in optimade/models/optimade_json.py
 29
 30
 31
 32
 33
 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
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
class DataType(Enum):
    """Optimade Data types

    See the section "Data types" in the OPTIMADE API specification for more information.
    """

    STRING = "string"
    INTEGER = "integer"
    FLOAT = "float"
    BOOLEAN = "boolean"
    TIMESTAMP = "timestamp"
    LIST = "list"
    DICTIONARY = "dictionary"
    UNKNOWN = "unknown"

    @classmethod
    def get_values(cls) -> list[str]:
        """Get OPTIMADE data types (enum values) as a (sorted) list"""
        return sorted(_.value for _ in cls)

    @classmethod
    def from_python_type(
        cls, python_type: Union[type, str, object]
    ) -> Optional["DataType"]:
        """Get OPTIMADE data type from a Python type"""
        mapping = {
            "bool": cls.BOOLEAN,
            "int": cls.INTEGER,
            "float": cls.FLOAT,
            "complex": None,
            "generator": cls.LIST,
            "list": cls.LIST,
            "tuple": cls.LIST,
            "range": cls.LIST,
            "hash": cls.INTEGER,
            "str": cls.STRING,
            "bytes": cls.STRING,
            "bytearray": None,
            "memoryview": None,
            "set": cls.LIST,
            "frozenset": cls.LIST,
            "dict": cls.DICTIONARY,
            "dict_keys": cls.LIST,
            "dict_values": cls.LIST,
            "dict_items": cls.LIST,
            "Nonetype": cls.UNKNOWN,
            "None": cls.UNKNOWN,
            "datetime": cls.TIMESTAMP,
            "date": cls.TIMESTAMP,
            "time": cls.TIMESTAMP,
            "datetime.datetime": cls.TIMESTAMP,
            "datetime.date": cls.TIMESTAMP,
            "datetime.time": cls.TIMESTAMP,
        }

        if isinstance(python_type, type):
            python_type = python_type.__name__
        elif isinstance(python_type, object):
            if str(python_type) in mapping:
                python_type = str(python_type)
            else:
                python_type = type(python_type).__name__

        return mapping.get(python_type, None)

    @classmethod
    def from_json_type(cls, json_type: str) -> Optional["DataType"]:
        """Get OPTIMADE data type from a named JSON type"""
        mapping = {
            "string": cls.STRING,
            "integer": cls.INTEGER,
            "number": cls.FLOAT,  # actually includes both integer and float
            "object": cls.DICTIONARY,
            "array": cls.LIST,
            "boolean": cls.BOOLEAN,
            "null": cls.UNKNOWN,
            # OpenAPI "format"s:
            "double": cls.FLOAT,
            "float": cls.FLOAT,
            "int32": cls.INTEGER,
            "int64": cls.INTEGER,
            "date": cls.TIMESTAMP,
            "date-time": cls.TIMESTAMP,
            "password": cls.STRING,
            "byte": cls.STRING,
            "binary": cls.STRING,
            # Non-OpenAPI "format"s, but may still be used by pydantic/FastAPI
            "email": cls.STRING,
            "uuid": cls.STRING,
            "uri": cls.STRING,
            "hostname": cls.STRING,
            "ipv4": cls.STRING,
            "ipv6": cls.STRING,
        }

        return mapping.get(json_type, None)

BOOLEAN = 'boolean' class-attribute instance-attribute

DICTIONARY = 'dictionary' class-attribute instance-attribute

FLOAT = 'float' class-attribute instance-attribute

INTEGER = 'integer' class-attribute instance-attribute

LIST = 'list' class-attribute instance-attribute

STRING = 'string' class-attribute instance-attribute

TIMESTAMP = 'timestamp' class-attribute instance-attribute

UNKNOWN = 'unknown' class-attribute instance-attribute

from_json_type(json_type) classmethod

Get OPTIMADE data type from a named JSON type

Source code in optimade/models/optimade_json.py
 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
120
121
122
123
124
@classmethod
def from_json_type(cls, json_type: str) -> Optional["DataType"]:
    """Get OPTIMADE data type from a named JSON type"""
    mapping = {
        "string": cls.STRING,
        "integer": cls.INTEGER,
        "number": cls.FLOAT,  # actually includes both integer and float
        "object": cls.DICTIONARY,
        "array": cls.LIST,
        "boolean": cls.BOOLEAN,
        "null": cls.UNKNOWN,
        # OpenAPI "format"s:
        "double": cls.FLOAT,
        "float": cls.FLOAT,
        "int32": cls.INTEGER,
        "int64": cls.INTEGER,
        "date": cls.TIMESTAMP,
        "date-time": cls.TIMESTAMP,
        "password": cls.STRING,
        "byte": cls.STRING,
        "binary": cls.STRING,
        # Non-OpenAPI "format"s, but may still be used by pydantic/FastAPI
        "email": cls.STRING,
        "uuid": cls.STRING,
        "uri": cls.STRING,
        "hostname": cls.STRING,
        "ipv4": cls.STRING,
        "ipv6": cls.STRING,
    }

    return mapping.get(json_type, None)

from_python_type(python_type) classmethod

Get OPTIMADE data type from a Python type

Source code in optimade/models/optimade_json.py
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
@classmethod
def from_python_type(
    cls, python_type: Union[type, str, object]
) -> Optional["DataType"]:
    """Get OPTIMADE data type from a Python type"""
    mapping = {
        "bool": cls.BOOLEAN,
        "int": cls.INTEGER,
        "float": cls.FLOAT,
        "complex": None,
        "generator": cls.LIST,
        "list": cls.LIST,
        "tuple": cls.LIST,
        "range": cls.LIST,
        "hash": cls.INTEGER,
        "str": cls.STRING,
        "bytes": cls.STRING,
        "bytearray": None,
        "memoryview": None,
        "set": cls.LIST,
        "frozenset": cls.LIST,
        "dict": cls.DICTIONARY,
        "dict_keys": cls.LIST,
        "dict_values": cls.LIST,
        "dict_items": cls.LIST,
        "Nonetype": cls.UNKNOWN,
        "None": cls.UNKNOWN,
        "datetime": cls.TIMESTAMP,
        "date": cls.TIMESTAMP,
        "time": cls.TIMESTAMP,
        "datetime.datetime": cls.TIMESTAMP,
        "datetime.date": cls.TIMESTAMP,
        "datetime.time": cls.TIMESTAMP,
    }

    if isinstance(python_type, type):
        python_type = python_type.__name__
    elif isinstance(python_type, object):
        if str(python_type) in mapping:
            python_type = str(python_type)
        else:
            python_type = type(python_type).__name__

    return mapping.get(python_type, None)

get_values() classmethod

Get OPTIMADE data types (enum values) as a (sorted) list

Source code in optimade/models/optimade_json.py
44
45
46
47
@classmethod
def get_values(cls) -> list[str]:
    """Get OPTIMADE data types (enum values) as a (sorted) list"""
    return sorted(_.value for _ in cls)

Implementation

Bases: BaseModel

Information on the server implementation

Source code in optimade/models/optimade_json.py
238
239
240
241
242
243
244
245
246
247
248
249
250
251
252
253
254
255
256
257
258
259
260
261
262
263
264
265
266
267
268
269
270
271
272
273
274
275
276
class Implementation(BaseModel):
    """Information on the server implementation"""

    name: Annotated[
        Optional[str], StrictField(description="name of the implementation")
    ] = None

    version: Annotated[
        Optional[str],
        StrictField(description="version string of the current implementation"),
    ] = None

    homepage: Annotated[
        Optional[jsonapi.JsonLinkType],
        StrictField(
            description="A [JSON API links object](http://jsonapi.org/format/1.0/#document-links) pointing to the homepage of the implementation.",
        ),
    ] = None

    source_url: Annotated[
        Optional[jsonapi.JsonLinkType],
        StrictField(
            description="A [JSON API links object](http://jsonapi.org/format/1.0/#document-links) pointing to the implementation source, either downloadable archive or version control system.",
        ),
    ] = None

    maintainer: Annotated[
        Optional[ImplementationMaintainer],
        StrictField(
            description="A dictionary providing details about the maintainer of the implementation.",
        ),
    ] = None

    issue_tracker: Annotated[
        Optional[jsonapi.JsonLinkType],
        StrictField(
            description="A [JSON API links object](http://jsonapi.org/format/1.0/#document-links) pointing to the implementation's issue tracker.",
        ),
    ] = None

homepage: Annotated[Optional[jsonapi.JsonLinkType], StrictField(description='A [JSON API links object](http://jsonapi.org/format/1.0/#document-links) pointing to the homepage of the implementation.')] = None class-attribute instance-attribute

issue_tracker: Annotated[Optional[jsonapi.JsonLinkType], StrictField(description="A [JSON API links object](http://jsonapi.org/format/1.0/#document-links) pointing to the implementation's issue tracker.")] = None class-attribute instance-attribute

maintainer: Annotated[Optional[ImplementationMaintainer], StrictField(description='A dictionary providing details about the maintainer of the implementation.')] = None class-attribute instance-attribute

name: Annotated[Optional[str], StrictField(description='name of the implementation')] = None class-attribute instance-attribute

source_url: Annotated[Optional[jsonapi.JsonLinkType], StrictField(description='A [JSON API links object](http://jsonapi.org/format/1.0/#document-links) pointing to the implementation source, either downloadable archive or version control system.')] = None class-attribute instance-attribute

version: Annotated[Optional[str], StrictField(description='version string of the current implementation')] = None class-attribute instance-attribute

ImplementationMaintainer

Bases: BaseModel

Details about the maintainer of the implementation

Source code in optimade/models/optimade_json.py
230
231
232
233
234
235
class ImplementationMaintainer(BaseModel):
    """Details about the maintainer of the implementation"""

    email: Annotated[
        EmailStr, StrictField(description="the maintainer's email address")
    ]

email: Annotated[EmailStr, StrictField(description="the maintainer's email address")] instance-attribute

OptimadeError

Bases: Error

detail MUST be present

Source code in optimade/models/optimade_json.py
127
128
129
130
131
132
133
134
135
class OptimadeError(jsonapi.Error):
    """detail MUST be present"""

    detail: Annotated[
        str,
        StrictField(
            description="A human-readable explanation specific to this occurrence of the problem.",
        ),
    ]

code: Annotated[Optional[str], StrictField(description='an application-specific error code, expressed as a string value.')] = None class-attribute instance-attribute

detail: Annotated[str, StrictField(description='A human-readable explanation specific to this occurrence of the problem.')] instance-attribute

id: Annotated[Optional[str], StrictField(description='A unique identifier for this particular occurrence of the problem.')] = None class-attribute instance-attribute

meta: Annotated[Optional[Meta], StrictField(description='a meta object containing non-standard meta-information about the error.')] = None class-attribute instance-attribute

source: Annotated[Optional[ErrorSource], StrictField(description='An object containing references to the source of the error')] = None class-attribute instance-attribute

status: Annotated[Optional[Annotated[str, BeforeValidator(str)]], StrictField(description='the HTTP status code applicable to this problem, expressed as a string value.')] = None class-attribute instance-attribute

title: Annotated[Optional[str], StrictField(description='A short, human-readable summary of the problem. It **SHOULD NOT** change from occurrence to occurrence of the problem, except for purposes of localization.')] = None class-attribute instance-attribute

__hash__()

Source code in optimade/models/jsonapi.py
191
192
def __hash__(self):
    return hash(self.model_dump_json())

Provider

Bases: BaseModel

Information on the database provider of the implementation.

Source code in optimade/models/optimade_json.py
201
202
203
204
205
206
207
208
209
210
211
212
213
214
215
216
217
218
219
220
221
222
223
224
225
226
227
class Provider(BaseModel):
    """Information on the database provider of the implementation."""

    name: Annotated[
        str, StrictField(description="a short name for the database provider")
    ]

    description: Annotated[
        str, StrictField(description="a longer description of the database provider")
    ]

    prefix: Annotated[
        str,
        StrictField(
            pattern=r"^[a-z]([a-z]|[0-9]|_)*$",
            description="database-provider-specific prefix as found in section Database-Provider-Specific Namespace Prefixes.",
        ),
    ]

    homepage: Annotated[
        Optional[jsonapi.JsonLinkType],
        StrictField(
            description="a [JSON API links object](http://jsonapi.org/format/1.0#document-links) "
            "pointing to homepage of the database provider, either "
            "directly as a string, or as a link object.",
        ),
    ] = None

description: Annotated[str, StrictField(description='a longer description of the database provider')] instance-attribute

homepage: Annotated[Optional[jsonapi.JsonLinkType], StrictField(description='a [JSON API links object](http://jsonapi.org/format/1.0#document-links) pointing to homepage of the database provider, either directly as a string, or as a link object.')] = None class-attribute instance-attribute

name: Annotated[str, StrictField(description='a short name for the database provider')] instance-attribute

prefix: Annotated[str, StrictField(pattern='^[a-z]([a-z]|[0-9]|_)*$', description='database-provider-specific prefix as found in section Database-Provider-Specific Namespace Prefixes.')] instance-attribute

Relationship

Bases: Relationship

Similar to normal JSON API relationship, but with addition of OPTIONAL meta field for a resource.

Source code in optimade/models/optimade_json.py
426
427
428
429
430
431
432
class Relationship(jsonapi.Relationship):
    """Similar to normal JSON API relationship, but with addition of OPTIONAL meta field for a resource."""

    data: Annotated[
        Optional[Union[BaseRelationshipResource, list[BaseRelationshipResource]]],
        StrictField(description="Resource linkage", uniqueItems=True),
    ] = None

data: Annotated[Optional[Union[BaseRelationshipResource, list[BaseRelationshipResource]]], StrictField(description='Resource linkage', uniqueItems=True)] = None class-attribute instance-attribute

meta: Annotated[Optional[Meta], StrictField(description='a meta object that contains non-standard meta-information about the relationship.')] = None class-attribute instance-attribute

at_least_one_relationship_key_must_be_set()

Source code in optimade/models/jsonapi.py
279
280
281
282
283
284
285
@model_validator(mode="after")
def at_least_one_relationship_key_must_be_set(self) -> "Relationship":
    if self.links is None and self.data is None and self.meta is None:
        raise ValueError(
            "Either 'links', 'data', or 'meta' MUST be specified for Relationship"
        )
    return self

ResponseMeta

Bases: Meta

A JSON API meta member that contains JSON API meta objects of non-standard meta-information.

OPTIONAL additional information global to the query that is not specified in this document, MUST start with a database-provider-specific prefix.

Source code in optimade/models/optimade_json.py
279
280
281
282
283
284
285
286
287
288
289
290
291
292
293
294
295
296
297
298
299
300
301
302
303
304
305
306
307
308
309
310
311
312
313
314
315
316
317
318
319
320
321
322
323
324
325
326
327
328
329
330
331
332
333
334
335
336
337
338
339
340
341
342
343
344
345
346
347
348
349
350
351
352
353
354
355
356
357
358
359
360
361
362
363
364
365
366
367
368
369
370
371
372
373
374
375
376
377
class ResponseMeta(jsonapi.Meta):
    """
    A [JSON API meta member](https://jsonapi.org/format/1.0#document-meta)
    that contains JSON API meta objects of non-standard
    meta-information.

    OPTIONAL additional information global to the query that is not
    specified in this document, MUST start with a
    database-provider-specific prefix.
    """

    query: Annotated[
        ResponseMetaQuery,
        StrictField(description="Information on the Query that was requested"),
    ]

    api_version: Annotated[
        SemanticVersion,
        StrictField(
            description="""Presently used full version of the OPTIMADE API.
The version number string MUST NOT be prefixed by, e.g., "v".
Examples: `1.0.0`, `1.0.0-rc.2`.""",
        ),
    ]

    more_data_available: Annotated[
        bool,
        StrictField(
            description="`false` if the response contains all data for the request (e.g., a request issued to a single entry endpoint, or a `filter` query at the last page of a paginated response) and `true` if the response is incomplete in the sense that multiple objects match the request, and not all of them have been included in the response (e.g., a query with multiple pages that is not at the last page).",
        ),
    ]

    # start of "SHOULD" fields for meta response
    optimade_schema: Annotated[
        Optional[jsonapi.JsonLinkType],
        StrictField(
            alias="schema",
            description="""A [JSON API links object](http://jsonapi.org/format/1.0/#document-links) that points to a schema for the response.
If it is a string, or a dictionary containing no `meta` field, the provided URL MUST point at an [OpenAPI](https://swagger.io/specification/) schema.
It is possible that future versions of this specification allows for alternative schema types.
Hence, if the `meta` field of the JSON API links object is provided and contains a field `schema_type` that is not equal to the string `OpenAPI` the client MUST not handle failures to parse the schema or to validate the response against the schema as errors.""",
        ),
    ] = None

    time_stamp: Annotated[
        Optional[datetime],
        StrictField(
            description="A timestamp containing the date and time at which the query was executed.",
        ),
    ] = None

    data_returned: Annotated[
        Optional[int],
        StrictField(
            description="An integer containing the total number of data resource objects returned for the current `filter` query, independent of pagination.",
            ge=0,
        ),
    ] = None

    provider: Annotated[
        Optional[Provider],
        StrictField(
            description="information on the database provider of the implementation."
        ),
    ] = None

    # start of "MAY" fields for meta response
    data_available: Annotated[
        Optional[int],
        StrictField(
            description="An integer containing the total number of data resource objects available in the database for the endpoint.",
        ),
    ] = None

    last_id: Annotated[
        Optional[str],
        StrictField(description="a string containing the last ID returned"),
    ] = None

    response_message: Annotated[
        Optional[str], StrictField(description="response string from the server")
    ] = None

    implementation: Annotated[
        Optional[Implementation],
        StrictField(description="a dictionary describing the server implementation"),
    ] = None

    warnings: Annotated[
        Optional[list[Warnings]],
        StrictField(
            description="""A list of warning resource objects representing non-critical errors or warnings.
A warning resource object is defined similarly to a [JSON API error object](http://jsonapi.org/format/1.0/#error-objects), but MUST also include the field `type`, which MUST have the value `"warning"`.
The field `detail` MUST be present and SHOULD contain a non-critical message, e.g., reporting unrecognized search attributes or deprecated features.
The field `status`, representing a HTTP response status code, MUST NOT be present for a warning resource object.
This is an exclusive field for error resource objects.""",
            uniqueItems=True,
        ),
    ] = None

api_version: Annotated[SemanticVersion, StrictField(description='Presently used full version of the OPTIMADE API.\nThe version number string MUST NOT be prefixed by, e.g., "v".\nExamples: `1.0.0`, `1.0.0-rc.2`.')] instance-attribute

data_available: Annotated[Optional[int], StrictField(description='An integer containing the total number of data resource objects available in the database for the endpoint.')] = None class-attribute instance-attribute

data_returned: Annotated[Optional[int], StrictField(description='An integer containing the total number of data resource objects returned for the current `filter` query, independent of pagination.', ge=0)] = None class-attribute instance-attribute

implementation: Annotated[Optional[Implementation], StrictField(description='a dictionary describing the server implementation')] = None class-attribute instance-attribute

last_id: Annotated[Optional[str], StrictField(description='a string containing the last ID returned')] = None class-attribute instance-attribute

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

more_data_available: Annotated[bool, StrictField(description='`false` if the response contains all data for the request (e.g., a request issued to a single entry endpoint, or a `filter` query at the last page of a paginated response) and `true` if the response is incomplete in the sense that multiple objects match the request, and not all of them have been included in the response (e.g., a query with multiple pages that is not at the last page).')] instance-attribute

optimade_schema: Annotated[Optional[jsonapi.JsonLinkType], StrictField(alias=schema, description='A [JSON API links object](http://jsonapi.org/format/1.0/#document-links) that points to a schema for the response.\nIf it is a string, or a dictionary containing no `meta` field, the provided URL MUST point at an [OpenAPI](https://swagger.io/specification/) schema.\nIt is possible that future versions of this specification allows for alternative schema types.\nHence, if the `meta` field of the JSON API links object is provided and contains a field `schema_type` that is not equal to the string `OpenAPI` the client MUST not handle failures to parse the schema or to validate the response against the schema as errors.')] = None class-attribute instance-attribute

provider: Annotated[Optional[Provider], StrictField(description='information on the database provider of the implementation.')] = None class-attribute instance-attribute

query: Annotated[ResponseMetaQuery, StrictField(description='Information on the Query that was requested')] instance-attribute

response_message: Annotated[Optional[str], StrictField(description='response string from the server')] = None class-attribute instance-attribute

time_stamp: Annotated[Optional[datetime], StrictField(description='A timestamp containing the date and time at which the query was executed.')] = None class-attribute instance-attribute

warnings: Annotated[Optional[list[Warnings]], StrictField(description='A list of warning resource objects representing non-critical errors or warnings.\nA warning resource object is defined similarly to a [JSON API error object](http://jsonapi.org/format/1.0/#error-objects), but MUST also include the field `type`, which MUST have the value `"warning"`.\nThe field `detail` MUST be present and SHOULD contain a non-critical message, e.g., reporting unrecognized search attributes or deprecated features.\nThe field `status`, representing a HTTP response status code, MUST NOT be present for a warning resource object.\nThis is an exclusive field for error resource objects.', uniqueItems=True)] = None class-attribute instance-attribute

ResponseMetaQuery

Bases: BaseModel

Information on the query that was requested.

Source code in optimade/models/optimade_json.py
187
188
189
190
191
192
193
194
195
196
197
198
class ResponseMetaQuery(BaseModel):
    """Information on the query that was requested."""

    representation: Annotated[
        str,
        StrictField(
            description="""A string with the part of the URL following the versioned or unversioned base URL that serves the API.
Query parameters that have not been used in processing the request MAY be omitted.
In particular, if no query parameters have been involved in processing the request, the query part of the URL MAY be excluded.
Example: `/structures?filter=nelements=2`""",
        ),
    ]

representation: Annotated[str, StrictField(description='A string with the part of the URL following the versioned or unversioned base URL that serves the API.\nQuery parameters that have not been used in processing the request MAY be omitted.\nIn particular, if no query parameters have been involved in processing the request, the query part of the URL MAY be excluded.\nExample: `/structures?filter=nelements=2`')] instance-attribute

Success

Bases: Response

errors are not allowed

Source code in optimade/models/optimade_json.py
380
381
382
383
384
385
386
387
388
389
390
391
392
393
394
395
396
397
398
399
400
401
class Success(jsonapi.Response):
    """errors are not allowed"""

    meta: Annotated[
        ResponseMeta,
        StrictField(description="A meta object containing non-standard information"),
    ]

    @model_validator(mode="after")
    def either_data_meta_or_errors_must_be_set(self) -> "Success":
        """Overwriting the existing validation function, since 'errors' MUST NOT be set."""
        required_fields = ("data", "meta")
        if not any(field in self.model_fields_set for field in required_fields):
            raise ValueError(
                f"At least one of {required_fields} MUST be specified in the top-level response."
            )

        # errors MUST be skipped
        if self.errors or "errors" in self.model_fields_set:
            raise ValueError("'errors' MUST be skipped for a successful response.")

        return self

data: Annotated[Optional[Union[None, Resource, list[Resource]]], StrictField(description='Outputted Data', uniqueItems=True)] = None class-attribute instance-attribute

errors: Annotated[Optional[list[Error]], StrictField(description='A list of unique errors', uniqueItems=True)] = None class-attribute instance-attribute

included: Annotated[Optional[list[Resource]], StrictField(description='A list of unique included resources', uniqueItems=True)] = None class-attribute instance-attribute

jsonapi: Annotated[Optional[JsonApi], StrictField(description='Information about the JSON API used')] = None class-attribute instance-attribute

meta: Annotated[ResponseMeta, StrictField(description='A meta object containing non-standard information')] instance-attribute

model_config = ConfigDict(json_encoders={datetime: lambda v: v.astimezone(timezone.utc).strftime('%Y-%m-%dT%H:%M:%SZ')}) class-attribute instance-attribute

The specification mandates that datetimes must be encoded following RFC3339, which does not support fractional seconds, thus they must be stripped in the response. This can cause issues when the underlying database contains fields that do include microseconds, as filters may return unexpected results.

either_data_meta_or_errors_must_be_set()

Overwriting the existing validation function, since 'errors' MUST NOT be set.

Source code in optimade/models/optimade_json.py
388
389
390
391
392
393
394
395
396
397
398
399
400
401
@model_validator(mode="after")
def either_data_meta_or_errors_must_be_set(self) -> "Success":
    """Overwriting the existing validation function, since 'errors' MUST NOT be set."""
    required_fields = ("data", "meta")
    if not any(field in self.model_fields_set for field in required_fields):
        raise ValueError(
            f"At least one of {required_fields} MUST be specified in the top-level response."
        )

    # errors MUST be skipped
    if self.errors or "errors" in self.model_fields_set:
        raise ValueError("'errors' MUST be skipped for a successful response.")

    return self

Warnings

Bases: OptimadeError

OPTIMADE-specific warning class based on OPTIMADE-specific JSON API Error.

From the specification:

A warning resource object is defined similarly to a JSON API error object, but MUST also include the field type, which MUST have the value "warning". The field detail MUST be present and SHOULD contain a non-critical message, e.g., reporting unrecognized search attributes or deprecated features.

Note: Must be named "Warnings", since "Warning" is a built-in Python class.

Source code in optimade/models/optimade_json.py
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
class Warnings(OptimadeError):
    """OPTIMADE-specific warning class based on OPTIMADE-specific JSON API Error.

    From the specification:

    A warning resource object is defined similarly to a JSON API error object, but MUST also include the field type, which MUST have the value "warning".
    The field detail MUST be present and SHOULD contain a non-critical message, e.g., reporting unrecognized search attributes or deprecated features.

    Note: Must be named "Warnings", since "Warning" is a built-in Python class.

    """

    model_config = ConfigDict(json_schema_extra=warnings_json_schema_extra)

    type: Annotated[
        Literal["warning"],
        StrictField(
            description='Warnings must be of type "warning"',
            pattern="^warning$",
        ),
    ] = "warning"

    @model_validator(mode="after")
    def status_must_not_be_specified(self) -> "Warnings":
        if self.status or "status" in self.model_fields_set:
            raise ValueError("status MUST NOT be specified for warnings")
        return self

code: Annotated[Optional[str], StrictField(description='an application-specific error code, expressed as a string value.')] = None class-attribute instance-attribute

detail: Annotated[str, StrictField(description='A human-readable explanation specific to this occurrence of the problem.')] instance-attribute

id: Annotated[Optional[str], StrictField(description='A unique identifier for this particular occurrence of the problem.')] = None class-attribute instance-attribute

meta: Annotated[Optional[Meta], StrictField(description='a meta object containing non-standard meta-information about the error.')] = None class-attribute instance-attribute

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

source: Annotated[Optional[ErrorSource], StrictField(description='An object containing references to the source of the error')] = None class-attribute instance-attribute

status: Annotated[Optional[Annotated[str, BeforeValidator(str)]], StrictField(description='the HTTP status code applicable to this problem, expressed as a string value.')] = None class-attribute instance-attribute

title: Annotated[Optional[str], StrictField(description='A short, human-readable summary of the problem. It **SHOULD NOT** change from occurrence to occurrence of the problem, except for purposes of localization.')] = None class-attribute instance-attribute

type: Annotated[Literal['warning'], StrictField(description='Warnings must be of type "warning"', pattern='^warning$')] = 'warning' class-attribute instance-attribute

__hash__()

Source code in optimade/models/jsonapi.py
191
192
def __hash__(self):
    return hash(self.model_dump_json())

status_must_not_be_specified()

Source code in optimade/models/optimade_json.py
180
181
182
183
184
@model_validator(mode="after")
def status_must_not_be_specified(self) -> "Warnings":
    if self.status or "status" in self.model_fields_set:
        raise ValueError("status MUST NOT be specified for warnings")
    return self

warnings_json_schema_extra(schema, model)

Update OpenAPI JSON schema model for Warning.

  • Ensure type is in the list required properties and in the correct place.
  • Remove status property. This property is not allowed for Warning, nor is it a part of the OPTIMADE definition of the Warning object.
Note

Since type is the last model field defined, it will simply be appended.

Source code in optimade/models/optimade_json.py
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
def warnings_json_schema_extra(schema: dict[str, Any], model: type["Warnings"]) -> None:
    """Update OpenAPI JSON schema model for `Warning`.

    * Ensure `type` is in the list required properties and in the correct place.
    * Remove `status` property.
        This property is not allowed for `Warning`, nor is it a part of the OPTIMADE
        definition of the `Warning` object.

    Note:
        Since `type` is the _last_ model field defined, it will simply be appended.

    """
    if "required" in schema:
        if "type" not in schema["required"]:
            schema["required"].append("type")
        else:
            schema["required"] = ["type"]
    schema.get("properties", {}).pop("status", None)