Skip to content

Commit

Permalink
Remove nullable field from properties
Browse files Browse the repository at this point in the history
This is no longer part of the OpenAPI spec as of v3.1.

Fixes #1814
  • Loading branch information
CasperWA committed Oct 14, 2023
1 parent 9e50994 commit b7c5588
Show file tree
Hide file tree
Showing 3 changed files with 2 additions and 38 deletions.
7 changes: 1 addition & 6 deletions openapi/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -4125,7 +4125,6 @@
],
"title": "Last Modified",
"description": "Date and time representing when the entry was last modified.\n\n- **Type**: timestamp.\n\n- **Requirements/Conventions**:\n - **Support**: SHOULD be supported by all implementations, i.e., SHOULD NOT be `null`.\n - **Query**: MUST be a queryable property with support for all mandatory filter features.\n - **Response**: REQUIRED in the response unless the query parameter `response_fields` is present and does not include this property.\n\n- **Example**:\n - As part of JSON response format: `\"2007-04-05T14:30:20Z\"` (i.e., encoded as an [RFC 3339 Internet Date/Time Format](https://tools.ietf.org/html/rfc3339#section-5.6) string.)",
"nullable": true,
"x-optimade-queryable": "must",
"x-optimade-support": "should"
},
Expand Down Expand Up @@ -4255,7 +4254,6 @@
],
"title": "Dimension Types",
"description": "List of three integers.\nFor each of the three directions indicated by the three lattice vectors (see property `lattice_vectors`), this list indicates if the direction is periodic (value `1`) or non-periodic (value `0`).\nNote: the elements in this list each refer to the direction of the corresponding entry in `lattice_vectors` and *not* the Cartesian x, y, z directions.\n\n- **Type**: list of integers.\n\n- **Requirements/Conventions**:\n - **Support**: SHOULD be supported by all implementations, i.e., SHOULD NOT be `null`.\n - **Query**: Support for queries on this property is OPTIONAL.\n - MUST be a list of length 3.\n - Each integer element MUST assume only the value 0 or 1.\n\n- **Examples**:\n - For a molecule: `[0, 0, 0]`\n - For a wire along the direction specified by the third lattice vector: `[0, 0, 1]`\n - For a 2D surface/slab, periodic on the plane defined by the first and third lattice vectors: `[1, 0, 1]`\n - For a bulk 3D system: `[1, 1, 1]`",
"nullable": true,
"x-optimade-queryable": "optional",
"x-optimade-support": "should"
},
Expand Down Expand Up @@ -4301,7 +4299,6 @@
],
"title": "Lattice Vectors",
"description": "The three lattice vectors in Cartesian coordinates, in \u00e5ngstr\u00f6m (\u00c5).\n\n- **Type**: list of list of floats or unknown values.\n\n- **Requirements/Conventions**:\n - **Support**: SHOULD be supported by all implementations, i.e., SHOULD NOT be `null`.\n - **Query**: Support for queries on this property is OPTIONAL.\n If supported, filters MAY support only a subset of comparison operators.\n - MUST be a list of three vectors *a*, *b*, and *c*, where each of the vectors MUST BE a list of the vector's coordinates along the x, y, and z Cartesian coordinates.\n (Therefore, the first index runs over the three lattice vectors and the second index runs over the x, y, z Cartesian coordinates).\n - For databases that do not define an absolute Cartesian system (e.g., only defining the length and angles between vectors), the first lattice vector SHOULD be set along *x* and the second on the *xy*-plane.\n - MUST always contain three vectors of three coordinates each, independently of the elements of property `dimension_types`.\n The vectors SHOULD by convention be chosen so the determinant of the `lattice_vectors` matrix is different from zero.\n The vectors in the non-periodic directions have no significance beyond fulfilling these requirements.\n - The coordinates of the lattice vectors of non-periodic dimensions (i.e., those dimensions for which `dimension_types` is `0`) MAY be given as a list of all `null` values.\n If a lattice vector contains the value `null`, all coordinates of that lattice vector MUST be `null`.\n\n- **Examples**:\n - `[[4.0,0.0,0.0],[0.0,4.0,0.0],[0.0,1.0,4.0]]` represents a cell, where the first vector is `(4, 0, 0)`, i.e., a vector aligned along the `x` axis of length 4 \u00c5; the second vector is `(0, 4, 0)`; and the third vector is `(0, 1, 4)`.",
"nullable": true,
"x-optimade-queryable": "optional",
"x-optimade-support": "should",
"x-optimade-unit": "\u00c5"
Expand Down Expand Up @@ -4409,9 +4406,7 @@
"type": "object",
"required": [
"last_modified",
"structure_features",
"dimension_types",
"lattice_vectors"
"structure_features"
],
"title": "StructureResourceAttributes",
"description": "This class contains the Field for the attributes used to represent a structure, e.g. unit cell, atoms, positions."
Expand Down
32 changes: 1 addition & 31 deletions optimade/models/structures.py
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,11 @@
import re
import warnings
from enum import Enum, IntEnum
from typing import Annotated, Any, Dict, List, Optional, Set, Type, Union
from typing import Annotated, List, Optional, Set, Union

from pydantic import (
BaseModel,
BeforeValidator,
ConfigDict,
Field,
ValidationInfo,
field_validator,
Expand Down Expand Up @@ -272,38 +271,9 @@ def check_self_consistency(
)


def structure_json_schema_extra(
schema: Dict[str, Any], model: Type["StructureResourceAttributes"]
) -> None:
"""Two things need to be added to the schema:
1. Constrained types in pydantic do not currently play nicely with
"Required Optional" fields, i.e. fields must be specified but can be null.
The two constrained list fields, `dimension_types` and `lattice_vectors`,
are OPTIMADE 'SHOULD' fields, which means that they are allowed to be null.
2. All OPTIMADE 'SHOULD' fields are allowed to be null, so we manually set them
to be `nullable` according to the OpenAPI definition.
"""
schema["required"].insert(7, "dimension_types")
schema["required"].insert(9, "lattice_vectors")

nullable_props = (
prop
for prop in schema["required"]
if schema["properties"][prop].get("x-optimade-support")
== SupportLevel.SHOULD.value
)
for prop in nullable_props:
schema["properties"][prop]["nullable"] = True


class StructureResourceAttributes(EntryResourceAttributes):
"""This class contains the Field for the attributes used to represent a structure, e.g. unit cell, atoms, positions."""

model_config = ConfigDict(json_schema_extra=structure_json_schema_extra)

elements: Optional[List[str]] = OptimadeField(
None,
description="""The chemical symbols of the different elements present in the structure.
Expand Down
1 change: 0 additions & 1 deletion optimade/models/utils.py
Original file line number Diff line number Diff line change
Expand Up @@ -69,7 +69,6 @@ def StrictField(
allowed_keys = [
"pattern",
"uniqueItems",
"nullable",
] + OPTIMADE_SCHEMA_EXTENSION_KEYS
_banned = [k for k in kwargs if k not in set(_PYDANTIC_FIELD_KWARGS + allowed_keys)]

Expand Down

0 comments on commit b7c5588

Please sign in to comment.