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))