Source code for tdw_catalog.metadata.field

from datetime import date, datetime
import json
from typing import Generic, List, Optional, TypeVar
import uuid
from tdw_catalog.errors import CatalogFailedPreconditionException, CatalogPermissionDeniedException
import tdw_catalog.metadata_template.contract_owner as template_contract_owner
import tdw_catalog.metadata_template.currency as template_currency
import tdw_catalog.metadata_template.data_cost as template_data_cost
import tdw_catalog.metadata_template.date_field as template_date
import tdw_catalog.metadata_template.decimal as template_decimal
import tdw_catalog.metadata_template.license_expiry as template_license_expiry
import tdw_catalog.metadata_template.link as template_link
import tdw_catalog.metadata_template.field as field
import tdw_catalog.metadata_template.number as template_number
import tdw_catalog.metadata_template.organization_member as template_organization_member
import tdw_catalog.metadata_template.organization_team as template_organization_team
import tdw_catalog.metadata_template.point_in_time as template_point_in_time
import tdw_catalog.metadata_template.point_of_contact as template_point_of_contact
import tdw_catalog.metadata_template.text as template_text
import tdw_catalog.metadata_template.alias as template_alias
import tdw_catalog.metadata_template.list_field as template_list

from tdw_catalog.utils import MetadataFieldType

T = TypeVar('T')

from typing import TYPE_CHECKING
if TYPE_CHECKING:
    import tdw_catalog.dataset as dataset


[docs]class MetadataField(Generic[T]): """ The base type for all custom metadata fields which can be added to a :class:`.Dataset` Attributes ---------- key : str A key for this field, which must be unique among all metadata fields in a :class:`.Dataset` value : Optional[T] An optional value for :class:`.MetadataField`\\ s produced from this :class:`.MetadataField`. """ _key: str _value: Optional[T] def __init__( self, key: str, value: Optional[T], ) -> None: self._key = key self._value = value @property def key(self): return self._key @key.setter def key(self, key: str): self._key = key @property def value(self): return self._value @value.setter def value(self, value: Optional[T]): self._value = value @property def is_recommended(self) -> bool: return False def serialize(self) -> dict: res = { "key": self._key, } return res def __getitem__(self, item): return getattr(self, item) @classmethod def deserialize(cls, data: dict, dataset: 'dataset.Dataset') -> None: # if field_type is missing, assume string if "field_type" not in data: data["field_type"] = MetadataFieldType.FT_STRING if "value" not in data: data["value"] = "" # 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["value"]) if "value" in data else {} import tdw_catalog.metadata.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, ) elif "recommended_type" in data and data["recommended_type"] == "poc": import tdw_catalog.metadata.point_of_contact as point_of_contact try: return point_of_contact.Field( key=data["key"], value=dataset.organization.get_member( user_id=data["value"]), ) except: return point_of_contact.Field( key=data["key"], value=None, ) elif "recommended_type" in data and data[ "recommended_type"] == "expiryDate": import tdw_catalog.metadata.license_expiry as license_expiry return license_expiry.Field( key=data["key"], value=datetime.strptime(data["value"][0:10], "%Y-%m-%d").date() if "value" in data and len(data["value"]) == 10 else None, ) elif "recommended_type" in data and data[ "recommended_type"] == "contractOwner": import tdw_catalog.metadata.contract_owner as contract_owner try: return contract_owner.Field( key=data["key"], value=dataset.organization.get_team(team_id=data["value"]), ) except: return contract_owner.Field( key=data["key"], value=None, ) # determine field type and instantiate appropriate class elif data["field_type"] == MetadataFieldType.FT_STRING: import tdw_catalog.metadata.text as text return text.Field( key=data["key"], value=data["value"], ) elif data["field_type"] == MetadataFieldType.FT_INTEGER: import tdw_catalog.metadata.number as number return number.Field( key=data["key"], value=int(data["value"]), ) elif data["field_type"] == MetadataFieldType.FT_DECIMAL: import tdw_catalog.metadata.decimal as decimal return decimal.Field( key=data["key"], value=float(data["value"]), ) elif data["field_type"] == MetadataFieldType.FT_DATE: import tdw_catalog.metadata.date_field as date_field try: d = datetime.strptime(data["value"][0:10], "%Y-%m-%d").date() return date_field.Field( key=data["key"], value=d, ) except ValueError: return date_field.Field( key=data["key"], value=None, ) elif data["field_type"] == MetadataFieldType.FT_DATETIME: import tdw_catalog.metadata.point_in_time as point_in_time try: dt = datetime.fromisoformat(data["value"]) return point_in_time.Field( key=data["key"], value=dt, ) except ValueError: return point_in_time.Field( key=data["key"], value=None, ) elif data["field_type"] == MetadataFieldType.FT_DATASET: import tdw_catalog.metadata.linked_dataset as linked_dataset try: return linked_dataset.Field( key=data["key"], value=dataset.organization.get_dataset(id=data["value"]), ) except: return linked_dataset.Field( key=data["key"], value=None, ) elif data["field_type"] == MetadataFieldType.FT_URL: import tdw_catalog.metadata.link as link return link.Field( key=data["key"], value=data["value"], ) elif data["field_type"] == MetadataFieldType.FT_USER: import tdw_catalog.metadata.organization_member as organization_member try: return organization_member.Field( key=data["key"], value=dataset.organization.get_member( user_id=data["value"]), ) except: return organization_member.Field( key=data["key"], value=None, ) elif data["field_type"] == MetadataFieldType.FT_ATTACHMENT: import tdw_catalog.metadata.attachment as attachment return attachment.Field(key=data["key"], value=data["value"]) elif data["field_type"] == MetadataFieldType.FT_LIST: import tdw_catalog.metadata.list_field as list_field return list_field.Field( key=data["key"], value=data["value"], list_items=data["listValueList"] if "listValueList" in data else None, ) elif data["field_type"] == MetadataFieldType.FT_CURRENCY: currencyDict = json.loads(data["value"]) import tdw_catalog.metadata.currency as currency return currency.Field( key=data["key"], currency=currencyDict["currency"], amount=currencyDict["value"], ) elif data["field_type"] == MetadataFieldType.FT_TEAM: import tdw_catalog.metadata.organization_team as organization_team try: return organization_team.Field( key=data["key"], value=dataset.organization.get_team(team_id=data["value"]), ) except: return organization_team.Field( key=data["key"], value=None, ) elif data["field_type"] == MetadataFieldType.FT_ALIAS: import tdw_catalog.metadata.alias as alias return alias.Field( key=data["key"], value=data["value"], )
[docs]class TemplatedMetadataField(Generic[T]): """ A wrapper class for :class:`.MetadataField`\\ s that come from an attached :class:`.MetadataTemplate`. :class:`.TemplatedMetadataField`\\ s `key`\\ s can not be changed on a :class:`.Dataset`. """ _field: MetadataField[T] def __init__(self, field: MetadataField[T]): self._field = field @property def key(self): return self._field._key @key.setter def key(self, key: str): raise CatalogPermissionDeniedException( message= "Keys of fields on a MetadataTemplate can only be changed on the MetadataTemplate directly" ) @property def value(self): return self._field._value @value.setter def value(self, value: Optional[T]): self._field._value = value
[docs]class RecommendedMetadataField(MetadataField[T]): """ A subclass of :class:`.MetadataField` representing one of `license expiry`\\ , `point of contact`\\ , `data cost`\\ , or `contract owner`. The `key` of a :class:`.RecommendedMetadataField` cannot be changed """ def __init__(self, key: str, value: T): super().__init__(key, value) @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") @property def is_recommended() -> bool: return True
def _deserialize_metadata_fields( data: List[dict], dataset: 'dataset.Dataset') -> Optional[List[MetadataField]]: if data is None: return None return list(map(lambda d: MetadataField.deserialize(d, dataset), data)) def _convert_template_field( field: field.MetadataTemplateField[T]) -> MetadataField[T]: if isinstance(field, template_contract_owner.Field): import tdw_catalog.metadata.contract_owner as contract_owner return contract_owner.Field(key=field.key, value=field.default_value) if isinstance(field, template_point_of_contact.Field): import tdw_catalog.metadata.point_of_contact as point_of_contact return point_of_contact.Field(key=field.key, value=field.default_value) if isinstance(field, template_license_expiry.Field): import tdw_catalog.metadata.license_expiry as license_expiry return license_expiry.Field(key=field.key, value=field.default_value) if isinstance(field, template_data_cost.Field): currencyDict = field["default_value"] if field[ "default_value"] is not None else None import tdw_catalog.metadata.currency as currency import tdw_catalog.metadata.data_cost as data_cost currency = currencyDict.currency if currencyDict is not None else "" amount = currencyDict.value if currencyDict is not None else 0 return data_cost.Field(key=field.key, currency=currency, amount=amount) if isinstance(field, template_text.Field): import tdw_catalog.metadata.text as text return text.Field(key=field.key, value=field.default_value) if isinstance(field, template_number.Field): import tdw_catalog.metadata.number as number return number.Field(key=field.key, value=field.default_value) if isinstance(field, template_decimal.Field): import tdw_catalog.metadata.decimal as decimal return decimal.Field(key=field.key, value=field.default_value) if isinstance(field, template_link.Field): import tdw_catalog.metadata.link as link return link.Field(key=field.key, value=field.default_value) import tdw_catalog.metadata_template.linked_dataset as template_linked_dataset if isinstance(field, template_linked_dataset.Field): import tdw_catalog.metadata.linked_dataset as linked_dataset return linked_dataset.Field(key=field.key, value=field.default_value) if isinstance(field, template_date.Field): import tdw_catalog.metadata.date_field as date_field return date_field.Field(key=field.key, value=field.default_value) if isinstance(field, template_point_in_time.Field): import tdw_catalog.metadata.point_in_time as point_in_time return point_in_time.Field(key=field.key, value=field.default_value) if isinstance(field, template_organization_member.Field): import tdw_catalog.metadata.organization_member as organization_member return organization_member.Field(key=field.key, value=field.default_value) if isinstance(field, template_organization_team.Field): import tdw_catalog.metadata.organization_team as organization_team return organization_team.Field(key=field.key, value=field.default_value) if isinstance(field, template_alias.Field): import tdw_catalog.metadata.alias as alias return alias.Field(key=field.key, value=field.default_value) if isinstance(field, template_list.Field): import tdw_catalog.metadata.list_field as list_field return list_field.Field(key=field.key, value=field.default_value, list_items=field.list_items) def _check_field_match(field: MetadataField, templated_field: 'field.MetadataTemplateField') -> bool: if isinstance(templated_field, template_contract_owner.Field): import tdw_catalog.metadata.contract_owner as contract_owner return isinstance(field, contract_owner.Field) if isinstance(field, template_point_of_contact.Field): import tdw_catalog.metadata.point_of_contact as point_of_contact return isinstance(field, point_of_contact.Field) if isinstance(field, template_license_expiry.Field): import tdw_catalog.metadata.license_expiry as license_expiry return isinstance(field, license_expiry.Field) if isinstance(field, template_data_cost.Field): import tdw_catalog.metadata.data_cost as data_cost return isinstance(field, data_cost.Field) if isinstance(field, template_text.Field): import tdw_catalog.metadata.text as text return isinstance(field, text.Field) if isinstance(field, template_number.Field): import tdw_catalog.metadata.number as number return isinstance(field, number.Field) if isinstance(field, template_decimal.Field): import tdw_catalog.metadata.decimal as decimal return isinstance(field, decimal.Field) if isinstance(field, template_link.Field): import tdw_catalog.metadata.link as link return isinstance(field, link.Field) import tdw_catalog.metadata_template.linked_dataset as template_linked_dataset if isinstance(field, template_linked_dataset.Field): import tdw_catalog.metadata.linked_dataset as linked_dataset return isinstance(field, linked_dataset.Field) if isinstance(field, template_date.Field): import tdw_catalog.metadata.date_field as date_field return isinstance(field, date_field.Field) if isinstance(field, template_point_in_time.Field): import tdw_catalog.metadata.point_in_time as point_in_time return isinstance(field, point_in_time.Field) if isinstance(field, template_organization_member.Field): import tdw_catalog.metadata.organization_member as organization_member return isinstance(field, organization_member.Field) if isinstance(field, template_organization_team.Field): import tdw_catalog.metadata.organization_team as organization_team return isinstance(field, organization_team.Field) if isinstance(field, template_currency.Field): import tdw_catalog.metadata.currency as currency return isinstance(field, currency.Field) if isinstance(field, template_alias.Field): import tdw_catalog.metadata.alias as alias return isinstance(field, alias.Field) if isinstance(field, template_list.Field): import tdw_catalog.metadata.list_field as list_field return isinstance(field, list_field.Field)