from typing import Optional
from typing import Callable


def get_custom_attribute(item: dict, attribute_code: str, coerce_as: Optional[Callable] = None):
    """
    Get a custom attribute from an item given its code.

    For example:
        >>> get_custom_attribute(..., "my_custom_attribute")
        "0"

        >>> get_custom_attribute(..., "my_custom_attribute", bool)
        False

    :param item:
    :param attribute_code:
    :param coerce_as: optional callable that is called on the attribute value if it's set.
      This is useful to circumvent Magento's limitation where all attribute values are strings.
    :return: attribute value or None.
    """
    for attribute in item.get("custom_attributes", []):
        if attribute["attribute_code"] == attribute_code:
            value = attribute["value"]
            if coerce_as:
                if coerce_as == bool:
                    # "0" -> False / "1" -> True
                    return bool(int(value))
                return coerce_as(value)
            return value