Source code for tdw_catalog.metadata_template.field
from datetime import date, datetime
import json
from typing import Generic, List, Optional, TypeVar
import uuid
from tdw_catalog.errors import CatalogPermissionDeniedException
import tdw_catalog.metadata_template as metadata_template
from tdw_catalog.utils import MetadataFieldType
T = TypeVar('T')
[docs]class MetadataTemplateField(Generic[T]):
    """
    The base type for all metadata fields which can be added to a :class:`.MetadataTemplate`
    Attributes
    ----------
    key : str
        A key for this field, which must be unique within a :class:`.MetadataTemplate`.
    optional : Optional[bool]
        Determines whether a value must be supplied for this :class:`.MetadataTemplateField` when the corresponding :class:`.MetadataTemplate` is applied to a :class:`.Dataset`.
    default_value : Optional[T]
        An optional default value for :class:`MetadataField`\\ s produced from this :class:`.MetadataTemplateField`.
    """
    _default_value: Optional[T]
    id: str
    _key: str
    optional: Optional[bool]
    def __init__(
        self,
        key: str,
        default_value: Optional[T],
        optional: Optional[bool],
    ) -> None:
        self._key = key
        self._default_value = default_value
        self.id = str(uuid.uuid4())
        self.optional = optional
    @property
    def default_value(self):
        return self._default_value
    @default_value.setter
    def default_value(self, value: Optional[T]):
        self._default_value = value
    @property
    def key(self):
        return self._key
    @key.setter
    def key(self, key: str):
        self._key = key
    def serialize(self) -> dict:
        res = {
            "key": self._key,
        }
        if self.optional is not None:
            res["optional"] = self.optional
        return res
    def __getitem__(self, item):
        return getattr(self, item)
    @classmethod
    def deserialize(cls, data: dict,
                    template: 'metadata_template.MetadataTemplate') -> None:
        optional = True if "optional" in data and data[
            "optional"] == True else False
        # if field_type is missing, assume string
        if "field_type" not in data:
            data["field_type"] = MetadataFieldType.FT_STRING
        # if field_type comes back as a string, convert to int enum
        if isinstance(data["field_type"], str):
            data["field_type"] = MetadataFieldType[data["field_type"]]
        if "recommended_type" in data and data["recommended_type"] == "cost":
            currencyDict = json.loads(
                data["default_value"]) if "default_value" in data else {}
            import tdw_catalog.metadata_template.data_cost as data_cost
            return data_cost.Field(
                key=data["key"],
                currency=currencyDict["currency"] if "currency" in currencyDict else "",
                amount=currencyDict["value"] if "value" in currencyDict else 0,
                optional=optional)
        elif "recommended_type" in data and data["recommended_type"] == "poc":
            import tdw_catalog.metadata_template.point_of_contact as point_of_contact
            try:
                return point_of_contact.Field(
                    key=data["key"],
                    default_value=template.organization.get_member(
                        user_id=data["default_value"])
                    if "default_value" in data else None,
                    optional=optional,
                )
            except:
                return point_of_contact.Field(
                    key=data["key"],
                    default_value=None,
                    optional=optional,
                )
        elif "recommended_type" in data and data[
                "recommended_type"] == "expiryDate":
            import tdw_catalog.metadata_template.license_expiry as license_expiry
            return license_expiry.Field(
                key=data["key"],
                default_value=datetime.strptime(data["default_value"][0:10], "%Y-%m-%d").date()
                if "default_value" in data and len(data["default_value"]) == 10 else None,
                optional=False)
        elif "recommended_type" in data and data[
                "recommended_type"] == "contractOwner":
            import tdw_catalog.metadata_template.contract_owner as contract_owner
            try:
                return contract_owner.Field(
                    key=data["key"],
                    default_value=template.organization.get_team(
                        team_id=data["default_value"])
                    if "default_value" in data else None,
                    optional=optional,
                )
            except:
                return contract_owner.Field(
                    key=data["key"],
                    default_value=None,
                    optional=optional,
                )
        # determine field type and instantiate appropriate class
        elif data["field_type"] == MetadataFieldType.FT_STRING:
            import tdw_catalog.metadata_template.text as text
            return text.Field(
                key=data["key"],
                default_value=data["default_value"]
                if "default_value" in data else None,
                optional=optional,
            )
        elif data["field_type"] == MetadataFieldType.FT_INTEGER:
            import tdw_catalog.metadata_template.number as number
            default_value = None
            if "default_value" in data and data["default_value"] != 'None':
                default_value = int(data["default_value"])
            return number.Field(
                key=data["key"],
                default_value=default_value,
                optional=optional,
            )
        elif data["field_type"] == MetadataFieldType.FT_DECIMAL:
            import tdw_catalog.metadata_template.decimal as decimal
            default_value = None
            if "default_value" in data and data["default_value"] != 'None':
                default_value = float(data["default_value"])
            return decimal.Field(
                key=data["key"],
                default_value=default_value,
                optional=optional,
            )
        elif data["field_type"] == MetadataFieldType.FT_DATE:
            import tdw_catalog.metadata_template.date_field as date_field
            try:
                d = datetime.strptime(
                    data["default_value"][0:10],
                    "%Y-%m-%d").date() if "default_value" in data else None
                return date_field.Field(
                    key=data["key"],
                    default_value=d,
                    optional=optional,
                )
            except ValueError:
                return date_field.Field(
                    key=data["key"],
                    default_value=None,
                    optional=optional,
                )
        elif data["field_type"] == MetadataFieldType.FT_DATETIME:
            import tdw_catalog.metadata_template.point_in_time as point_in_time
            try:
                dt = datetime.fromisoformat(
                    data["default_value"]) if "default_value" in data else None
                return point_in_time.Field(
                    key=data["key"],
                    default_value=dt,
                    optional=optional,
                )
            except ValueError:
                return point_in_time.Field(
                    key=data["key"],
                    default_value=None,
                    optional=optional,
                )
        elif data["field_type"] == MetadataFieldType.FT_DATASET:
            import tdw_catalog.metadata_template.linked_dataset as linked_dataset
            try:
                return linked_dataset.Field(
                    key=data["key"],
                    default_value=template.organization.get_dataset(
                        id=data["value"]) if "default_value" in data else None,
                    optional=optional,
                )
            except:
                return linked_dataset.Field(
                    key=data["key"],
                    default_value=None,
                    optional=optional,
                )
        elif data["field_type"] == MetadataFieldType.FT_URL:
            import tdw_catalog.metadata_template.link as link
            return link.Field(
                key=data["key"],
                default_value=data["default_value"]
                if "default_value" in data else None,
                optional=optional,
            )
        elif data["field_type"] == MetadataFieldType.FT_USER:
            import tdw_catalog.metadata_template.organization_member as organization_member
            try:
                return organization_member.Field(
                    key=data["key"],
                    default_value=template.organization.get_member(
                        user_id=data["default_value"])
                    if "default_value" in data else None,
                    optional=optional,
                )
            except:
                return organization_member.Field(
                    key=data["key"],
                    default_value=None,
                    optional=optional,
                )
        elif data["field_type"] == MetadataFieldType.FT_ATTACHMENT:
            import tdw_catalog.metadata_template.attachment as attachment
            return attachment.Field(key=data["key"], optional=optional)
        elif data["field_type"] == MetadataFieldType.FT_LIST:
            import tdw_catalog.metadata_template.list_field as list_field
            return list_field.Field(
                key=data["key"],
                default_value=data["default_value"]
                if "default_value" in data else None,
                optional=optional,
                allow_any=data["allow_any"] if "allow_any" in data else None,
                list_items=data["listValueList"]
                if "listValueList" in data else None,
            )
        elif data["field_type"] == MetadataFieldType.FT_CURRENCY:
            currencyDict = json.loads(
                data["default_value"]) if "default_value" in data else None
            import tdw_catalog.metadata_template.currency as currency
            return currency.Field(key=data["key"],
                                  currency=currencyDict["currency"]
                                  if currencyDict is not None else None,
                                  amount=currencyDict["value"]
                                  if currencyDict is not None else None,
                                  optional=optional)
        elif data["field_type"] == MetadataFieldType.FT_TEAM:
            import tdw_catalog.metadata_template.organization_team as organization_team
            try:
                return organization_team.Field(
                    key=data["key"],
                    default_value=template.organization.get_team(
                        team_id=data["default_value"])
                    if "default_value" in data else None,
                    optional=optional,
                )
            except:
                return organization_team.Field(
                    key=data["key"],
                    default_value=None,
                    optional=optional,
                )
        elif data["field_type"] == MetadataFieldType.FT_ALIAS:
            import tdw_catalog.metadata_template.alias as alias
            return alias.Field(
                key=data["key"],
                default_value=data["default_value"]
                if "default_value" in data else None,
                optional=optional,
            )
[docs]class RecommendedTemplateMetadataField(MetadataTemplateField[T]):
    def __init__(self,
                 key: str,
                 default_value: Optional[T] = None,
                 optional=False):
        super().__init__(key, default_value, optional)
    @property
    def key(self):
        return super().key
    @key.setter
    def key(self, key: str):
        raise CatalogPermissionDeniedException(
            message="Keys of recommended metadata fields may not be changed")
def _deserialize_metadata_template_fields(
    data: List[dict], template: 'metadata_template.MetadataTemplate'
) -> Optional[List[MetadataTemplateField]]:
    if data is None:
        return None
    return list(
        map(lambda d: MetadataTemplateField.deserialize(d, template), data))