Skip to content

utils

clean_python_types(data) async

Turn any types into MongoDB-friendly Python types.

Use dict() method for Pydantic models. Use value property for Enums. Turn tuples and sets into lists.

Source code in optimade_gateway/common/utils.py
async def clean_python_types(data: Any) -> Any:
    """Turn any types into MongoDB-friendly Python types.

    Use `dict()` method for Pydantic models.
    Use `value` property for Enums.
    Turn tuples and sets into lists.
    """
    if isinstance(data, (list, tuple, set)):
        res = []
        for datum in data:
            res.append(await clean_python_types(datum))
    elif isinstance(data, dict):
        res = {}
        for key in list(data.keys()):
            res[key] = await clean_python_types(data[key])
    elif isinstance(data, BaseModel):
        # Pydantic model
        res = await clean_python_types(data.dict())
    elif isinstance(data, Enum):
        res = await clean_python_types(data.value)
    elif isinstance(data, type):
        res = await clean_python_types(f"{data.__module__}.{data.__name__}")
    else:
        # Unknown or other basic type, e.g., str, int, etc.
        res = data
    return res

get_resource_attribute(resource, field, default=None, disambiguate=True)

Return a resource's field's value

Get the field value no matter if the resource is a pydantic model or a Python dictionary.

Determine ambiguous field values and return them if desired (disambiguate). For example, if "attributes.base_url" is requested for a LinksResource it can be either a string, a Link model or a dictionary resembling the Link model.

Parameters:

Name Type Description Default
resource Union[pydantic.main.BaseModel, Dict[str, Any]]

The resource, from which to get the field value.

required
field str

The resource field. This can be a comma-separated nested field, e.g., "attributes.base_url".

required
default Any

The default value to return if field does not exist.

None
disambiguate bool

Whether or not to "shortcut" a field value. For example, for attributes.base_url, if True, this would return the string value or the value of it's "href" key.

True

Returns:

Type Description
Any

The resource's field's value.

Source code in optimade_gateway/common/utils.py
def get_resource_attribute(
    resource: Union[BaseModel, Dict[str, Any]],
    field: str,
    default: Any = None,
    disambiguate: bool = True,
) -> Any:
    """Return a resource's field's value

    Get the field value no matter if the resource is a pydantic model or a Python dictionary.

    Determine ambiguous field values and return them if desired (`disambiguate`).
    For example, if
    [`"attributes.base_url"`](https://www.optimade.org/optimade-python-tools/api_reference/models/links/#optimade.models.links.LinksResourceAttributes.base_url)
    is requested for a
    [`LinksResource`](https://www.optimade.org/optimade-python-tools/api_reference/models/links/#optimade.models.links.LinksResource)
    it can be either a string, a
    [`Link`](https://www.optimade.org/optimade-python-tools/api_reference/models/jsonapi/#optimade.models.jsonapi.Link)
    model or a dictionary resembling the `Link` model.

    Parameters:
        resource: The resource, from which to get the field value.
        field: The resource field. This can be a comma-separated nested field, e.g.,
            `"attributes.base_url"`.
        default: The default value to return if `field` does not exist.
        disambiguate: Whether or not to "shortcut" a field value.
            For example, for `attributes.base_url`, if `True`, this would return the string value
            or the value of it's `"href"` key.

    Returns:
        The resource's field's value.

    """
    if isinstance(resource, BaseModel):
        _get_attr = getattr
    elif isinstance(resource, dict):

        def _get_attr(mapping: dict, key: str, default: Any) -> Any:
            return mapping.get(key, default)

    else:
        raise TypeError(
            "resource must be either a pydantic model or a Python dictionary, it was of type "
            f"{type(resource)!r}"
        )

    fields = field.split(".")
    for field in fields[:-1]:
        resource = _get_attr(resource, field, {})
    field = fields[-1]
    value = _get_attr(resource, field, default)

    if disambiguate:
        if field in ("base_url", "next", "prev", "last", "first"):
            if not isinstance(value, str):
                value = _get_attr(value, "href", default)

    return value
Back to top