Skip to content

gateways

Pydantic models/schemas for the Gateways resource.

GatewayCreate

Bases: EntryResourceCreate, GatewayResourceAttributes

Model for creating new Gateway resources in the MongoDB

Source code in optimade_gateway/models/gateways.py
112
113
114
115
116
117
118
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
class GatewayCreate(EntryResourceCreate, GatewayResourceAttributes):
    """Model for creating new Gateway resources in the MongoDB"""

    id: Optional[str] = OptimadeField(
        None,
        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.
    - **Gateway-specific**: MUST NOT contain a forward slash (`/`).

- **Examples**:
    - `"db_1234567"`
    - `"cod_2000000"`
    - `"cod_2000000@1234567"`
    - `"nomad_L1234567890"`
    - `"42"`""",
        support=SupportLevel.MUST,
        queryable=SupportLevel.MUST,
        regex=r"^[^/]*$",  # This regex is the special addition
    )

    database_ids: Optional[Set[str]] = Field(
        None, description="A unique list of database IDs for registered databases."
    )

    databases: Optional[List[LinksResource]]  # type: ignore

    @root_validator
    def specify_databases(cls, values: dict) -> dict:
        """Either `database_ids` or `databases` must be non-empty.
        Both together is also fine.
        """
        if not any(values.get(field) for field in ("database_ids", "databases")):
            raise ValueError("Either 'database_ids' or 'databases' MUST be specified")
        return values

database_ids: Optional[Set[str]] = Field(None, description='A unique list of database IDs for registered databases.') class-attribute

databases: Optional[List[LinksResource]] class-attribute

id: Optional[str] = OptimadeField(None, 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\n features.\n - **Response**: REQUIRED in the response.\n - **Gateway-specific**: MUST NOT contain a forward slash (`/`).\n\n- **Examples**:\n - `"db_1234567"`\n - `"cod_2000000"`\n - `"cod_2000000@1234567"`\n - `"nomad_L1234567890"`\n - `"42"`', support=SupportLevel.MUST, queryable=SupportLevel.MUST, regex='^[^/]*$') class-attribute

specify_databases(values)

Either database_ids or databases must be non-empty. Both together is also fine.

Source code in optimade_gateway/models/gateways.py
145
146
147
148
149
150
151
152
@root_validator
def specify_databases(cls, values: dict) -> dict:
    """Either `database_ids` or `databases` must be non-empty.
    Both together is also fine.
    """
    if not any(values.get(field) for field in ("database_ids", "databases")):
        raise ValueError("Either 'database_ids' or 'databases' MUST be specified")
    return values

GatewayResource

Bases: EntryResource

OPTIMADE gateway

A resource representing a dynamic collection of OPTIMADE databases. The gateway can be treated as any other OPTIMADE gateway, but the entries are an aggregate of multiple databases. The id of each aggregated resource will reflect the originating database.

Source code in optimade_gateway/models/gateways.py
 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
class GatewayResource(EntryResource):
    """OPTIMADE gateway

    A resource representing a dynamic collection of OPTIMADE databases.
    The gateway can be treated as any other OPTIMADE gateway, but the entries are an
    aggregate of multiple databases. The `id` of each aggregated resource will reflect
    the originating database.
    """

    id: 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.
    - **Gateway-specific**: MUST NOT contain a forward slash (`/`).

- **Examples**:
    - `"db_1234567"`
    - `"cod_2000000"`
    - `"cod_2000000@1234567"`
    - `"nomad_L1234567890"`
    - `"42"`""",
        support=SupportLevel.MUST,
        queryable=SupportLevel.MUST,
        regex=r"^[^/]*$",
    )
    type: str = Field(
        "gateways",
        const=True,
        description="The name of the type of an entry.",
        regex="^gateways$",
    )
    attributes: GatewayResourceAttributes

attributes: GatewayResourceAttributes class-attribute

id: str = OptimadeField(Ellipsis, 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\n features.\n - **Response**: REQUIRED in the response.\n - **Gateway-specific**: MUST NOT contain a forward slash (`/`).\n\n- **Examples**:\n - `"db_1234567"`\n - `"cod_2000000"`\n - `"cod_2000000@1234567"`\n - `"nomad_L1234567890"`\n - `"42"`', support=SupportLevel.MUST, queryable=SupportLevel.MUST, regex='^[^/]*$') class-attribute

type: str = Field('gateways', const=True, description='The name of the type of an entry.', regex='^gateways$') class-attribute

GatewayResourceAttributes

Bases: EntryResourceAttributes

Attributes for an OPTIMADE gateway

Source code in optimade_gateway/models/gateways.py
16
17
18
19
20
21
22
23
24
25
26
27
28
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
class GatewayResourceAttributes(EntryResourceAttributes):
    """Attributes for an OPTIMADE gateway"""

    databases: List[LinksResource] = Field(
        ...,
        description="List of databases (OPTIMADE 'links') to be queried in this gateway.",
    )

    @validator("databases", each_item=True)
    def no_index_databases(cls, value: LinksResource) -> LinksResource:
        """Ensure databases are not of type `"root"` or `"providers"`

        !!! note
            Both `"external"` and `"child"` can still represent index meta-dbs,
            but `"root"` and `"providers"` can not represent "regular" dbs.
        """
        if value.attributes.link_type in (LinkType.ROOT, LinkType.PROVIDERS):
            raise ValueError(
                "Databases with 'root' or 'providers' link_type is not allowed for "
                f"gateway resources. Given database: {value}"
            )
        return value

    @validator("databases")
    def unique_base_urls(cls, value: List[LinksResource]) -> List[LinksResource]:
        """Remove extra entries with repeated base_urls"""
        db_base_urls = [_.attributes.base_url for _ in value]
        unique_base_urls = set(db_base_urls)
        if len(db_base_urls) == len(unique_base_urls):
            return value

        repeated_base_urls = [_ for _ in unique_base_urls if db_base_urls.count(_) > 1]
        new_databases = [
            _ for _ in value if _.attributes.base_url not in repeated_base_urls
        ]
        for base_url in repeated_base_urls:
            new_databases.append(
                [_ for _ in value if _.attributes.base_url == base_url][0]
            )
        warnings.warn(
            "Removed extra database entries for a gateway, because the base_url was "
            "repeated. The first found database entry was kept, while the others were "
            f"removed. Original number of databases: {len(value)}. New number of "
            f"databases: {len(new_databases)} Repeated base_urls (number of repeats): "
            "{}".format(
                [
                    f"{base_url} ({db_base_urls.count(base_url)})"
                    for base_url in repeated_base_urls
                ]
            ),
            OptimadeGatewayWarning,
        )
        return new_databases

databases: List[LinksResource] = Field(Ellipsis, description="List of databases (OPTIMADE 'links') to be queried in this gateway.") class-attribute

no_index_databases(value)

Ensure databases are not of type "root" or "providers"

Note

Both "external" and "child" can still represent index meta-dbs, but "root" and "providers" can not represent "regular" dbs.

Source code in optimade_gateway/models/gateways.py
24
25
26
27
28
29
30
31
32
33
34
35
36
37
@validator("databases", each_item=True)
def no_index_databases(cls, value: LinksResource) -> LinksResource:
    """Ensure databases are not of type `"root"` or `"providers"`

    !!! note
        Both `"external"` and `"child"` can still represent index meta-dbs,
        but `"root"` and `"providers"` can not represent "regular" dbs.
    """
    if value.attributes.link_type in (LinkType.ROOT, LinkType.PROVIDERS):
        raise ValueError(
            "Databases with 'root' or 'providers' link_type is not allowed for "
            f"gateway resources. Given database: {value}"
        )
    return value

unique_base_urls(value)

Remove extra entries with repeated base_urls

Source code in optimade_gateway/models/gateways.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
@validator("databases")
def unique_base_urls(cls, value: List[LinksResource]) -> List[LinksResource]:
    """Remove extra entries with repeated base_urls"""
    db_base_urls = [_.attributes.base_url for _ in value]
    unique_base_urls = set(db_base_urls)
    if len(db_base_urls) == len(unique_base_urls):
        return value

    repeated_base_urls = [_ for _ in unique_base_urls if db_base_urls.count(_) > 1]
    new_databases = [
        _ for _ in value if _.attributes.base_url not in repeated_base_urls
    ]
    for base_url in repeated_base_urls:
        new_databases.append(
            [_ for _ in value if _.attributes.base_url == base_url][0]
        )
    warnings.warn(
        "Removed extra database entries for a gateway, because the base_url was "
        "repeated. The first found database entry was kept, while the others were "
        f"removed. Original number of databases: {len(value)}. New number of "
        f"databases: {len(new_databases)} Repeated base_urls (number of repeats): "
        "{}".format(
            [
                f"{base_url} ({db_base_urls.count(base_url)})"
                for base_url in repeated_base_urls
            ]
        ),
        OptimadeGatewayWarning,
    )
    return new_databases