Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Update types to align with OpenAPI #480

Merged
merged 2 commits into from
Aug 31, 2020
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
19 changes: 12 additions & 7 deletions openapi/index_openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -778,17 +778,21 @@
"IndexInfoResource": {
"title": "IndexInfoResource",
"required": [
"id",
"type",
"attributes",
"relationships"
],
"type": "object",
"properties": {
"id": {
"title": "Id",
"pattern": "^/$",
"type": "string"
},
"type": {
"title": "Type",
"pattern": "^info$",
"type": "string"
},
"links": {
Expand Down Expand Up @@ -970,6 +974,7 @@
"title": "LinksResource",
"required": [
"id",
"type",
"attributes"
],
"type": "object",
Expand All @@ -981,6 +986,7 @@
},
"type": {
"title": "Type",
"pattern": "^links$",
"type": "string",
"description": "These objects are described in detail in the section Links Endpoint"
},
Expand Down Expand Up @@ -1326,7 +1332,8 @@
"RelatedLinksResource": {
"title": "RelatedLinksResource",
"required": [
"id"
"id",
"type"
],
"type": "object",
"properties": {
Expand All @@ -1337,6 +1344,7 @@
},
"type": {
"title": "Type",
"pattern": "^links$",
"type": "string"
}
},
Expand Down Expand Up @@ -1719,7 +1727,8 @@
"Warnings": {
"title": "Warnings",
"required": [
"detail"
"detail",
"type"
],
"type": "object",
"properties": {
Expand All @@ -1737,11 +1746,6 @@
],
"description": "A links object storing about"
},
"status": {
"title": "Status",
"type": "string",
"description": "the HTTP status code applicable to this problem, expressed as a string value."
},
"code": {
"title": "Code",
"type": "string",
Expand Down Expand Up @@ -1777,6 +1781,7 @@
},
"type": {
"title": "Type",
"pattern": "^warning$",
"type": "string",
"description": "Warnings must be of type \"warning\""
}
Expand Down
103 changes: 32 additions & 71 deletions openapi/openapi.json
Original file line number Diff line number Diff line change
Expand Up @@ -1095,16 +1095,20 @@
"BaseInfoResource": {
"title": "BaseInfoResource",
"required": [
"id",
"type",
"attributes"
],
"type": "object",
"properties": {
"id": {
"title": "Id",
"pattern": "^/$",
"type": "string"
},
"type": {
"title": "Type",
"pattern": "^info$",
"type": "string"
},
"links": {
Expand Down Expand Up @@ -1822,6 +1826,7 @@
"title": "LinksResource",
"required": [
"id",
"type",
"attributes"
],
"type": "object",
Expand All @@ -1833,6 +1838,7 @@
},
"type": {
"title": "Type",
"pattern": "^links$",
"type": "string",
"description": "These objects are described in detail in the section Links Endpoint"
},
Expand Down Expand Up @@ -2211,6 +2217,7 @@
"title": "ReferenceResource",
"required": [
"id",
"type",
"attributes"
],
"type": "object",
Expand All @@ -2222,6 +2229,7 @@
},
"type": {
"title": "Type",
"pattern": "^references$",
"type": "string",
"description": "The name of the type of an entry.\n- **Type**: string.\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- **Example**: `\"structures\"`"
},
Expand Down Expand Up @@ -2930,6 +2938,7 @@
"title": "StructureResource",
"required": [
"id",
"type",
"attributes"
],
"type": "object",
Expand All @@ -2941,6 +2950,7 @@
},
"type": {
"title": "Type",
"pattern": "^structures$",
"type": "string",
"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- **Examples**:\n - `\"structures\"`"
},
Expand Down Expand Up @@ -3050,18 +3060,12 @@
},
"dimension_types": {
"title": "Dimension Types",
"maxItems": 3,
"minItems": 3,
"type": "array",
"items": [
{
"$ref": "#/components/schemas/Periodicity"
},
{
"$ref": "#/components/schemas/Periodicity"
},
{
"$ref": "#/components/schemas/Periodicity"
}
],
"items": {
"$ref": "#/components/schemas/Periodicity"
},
"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]`"
},
"nperiodic_dimensions": {
Expand All @@ -3071,69 +3075,29 @@
},
"lattice_vectors": {
"title": "Lattice Vectors",
"maxItems": 3,
"minItems": 3,
"type": "array",
"items": [
{
"type": "array",
"items": [
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
}
]
},
{
"type": "array",
"items": [
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
}
]
"items": {
"type": "array",
"items": {
"type": "number"
},
{
"type": "array",
"items": [
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
}
]
}
],
"minItems": 3,
"maxItems": 3
},
"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)`."
},
"cartesian_site_positions": {
"title": "Cartesian Site Positions",
"type": "array",
"items": {
"type": "array",
"items": [
{
"type": "number"
},
{
"type": "number"
},
{
"type": "number"
}
]
"items": {
"type": "number"
},
"minItems": 3,
"maxItems": 3
},
"description": "Cartesian positions of each site in the structure.\nA site is usually used to describe positions of atoms; what atoms can be encountered at a given site is conveyed by the `species_at_sites` property, and the species themselves are described in the `species` property.\n\n- **Type**: list of list of floats\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 - It MUST be a list of length equal to the number of sites in the structure, where every element is a list of the three Cartesian coordinates of a site expressed as float values in the unit angstrom (\u00c5).\n - An entry MAY have multiple sites at the same Cartesian position (for a relevant use of this, see e.g., the property `assemblies`).\n\n- **Examples**:\n - `[[0,0,0],[0,0,2]]` indicates a structure with two sites, one sitting at the origin and one along the (positive) *z*-axis, 2 \u00c5 away from the origin."
},
Expand Down Expand Up @@ -3436,7 +3400,8 @@
"Warnings": {
"title": "Warnings",
"required": [
"detail"
"detail",
"type"
],
"type": "object",
"properties": {
Expand All @@ -3454,11 +3419,6 @@
],
"description": "A links object storing about"
},
"status": {
"title": "Status",
"type": "string",
"description": "the HTTP status code applicable to this problem, expressed as a string value."
},
"code": {
"title": "Code",
"type": "string",
Expand Down Expand Up @@ -3494,6 +3454,7 @@
},
"type": {
"title": "Type",
"pattern": "^warning$",
"type": "string",
"description": "Warnings must be of type \"warning\""
}
Expand Down
4 changes: 2 additions & 2 deletions optimade/models/baseinfo.py
Original file line number Diff line number Diff line change
Expand Up @@ -100,6 +100,6 @@ def formats_and_endpoints_must_be_valid(cls, v, values):


class BaseInfoResource(Resource):
id: str = Field(default="/", const=True)
type: str = Field(default="info", const=True)
id: str = Field("/", const="/", pattern="^/$")
type: str = Field("info", const="info", pattern="^info$")
attributes: BaseInfoAttributes = Field(...)
4 changes: 2 additions & 2 deletions optimade/models/index_metadb.py
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,7 @@ class IndexInfoAttributes(BaseInfoAttributes):
"""Attributes for Base URL Info endpoint for an Index Meta-Database"""

is_index: bool = Field(
default=True,
True,
const=True,
description="This must be `true` since this is an index meta-database (see section Index Meta-Database).",
)
Expand All @@ -35,7 +35,7 @@ class IndexInfoAttributes(BaseInfoAttributes):
class RelatedLinksResource(BaseResource):
"""A related Links resource object"""

type: str = Field("links", const=True)
type: str = Field("links", const="links", pattern="^links$")


class IndexRelationship(BaseModel):
Expand Down
24 changes: 23 additions & 1 deletion optimade/models/jsonapi.py
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
"""This module should reproduce JSON API v1.0 https://jsonapi.org/format/1.0/"""
# pylint: disable=no-self-argument
from typing import Optional, Union, List
from typing import Optional, Union, List, Dict, Any, Type
from datetime import datetime, timezone
from pydantic import ( # pylint: disable=no-name-in-module
BaseModel,
Expand Down Expand Up @@ -135,6 +135,28 @@ class BaseResource(BaseModel):
id: str = Field(..., description="Resource ID")
type: str = Field(..., description="Resource type")

class Config:
@staticmethod
def schema_extra(schema: Dict[str, Any], model: Type["BaseResource"]) -> None:
"""Ensure `id` and `type` are the first two entries in the list required properties.

Note:
This _requires_ that `id` and `type` are the _first_ model fields defined
for all sub-models of `BaseResource`.

"""
if "id" not in schema.get("required", []):
schema["required"] = ["id"] + schema.get("required", [])
if "type" not in schema.get("required", []):
required = []
for field in schema.get("required", []):
required.append(field)
if field == "id":
# To make sure the property order match the listed properties,
# this ensures "type" is added immediately after "id".
required.append("type")
schema["required"] = required


class RelationshipLinks(BaseModel):
"""A resource object **MAY** contain references to other resource objects ("relationships").
Expand Down
3 changes: 2 additions & 1 deletion optimade/models/links.py
Original file line number Diff line number Diff line change
Expand Up @@ -89,8 +89,9 @@ class LinksResource(EntryResource):

type: str = Field(
"links",
const=True,
const="links",
description="These objects are described in detail in the section Links Endpoint",
pattern="^links$",
)

attributes: LinksResourceAttributes = Field(
Expand Down
Loading