Source code for tdw_catalog.connection

from dataclasses import dataclass
from typing import TYPE_CHECKING, List, Optional, Union
from tdw_catalog import source
from tdw_catalog.entity import Entity, Property, EntityBase
from tdw_catalog.errors import CatalogException, _convert_error, _raise_error
from datetime import datetime

from tdw_catalog import Catalog
import tdw_catalog.credential as credential
from tdw_catalog.relations import _CredentialRelation, _SourceRelation
from tdw_catalog.utils import ConnectionPortalType

if TYPE_CHECKING:
    import tdw_catalog.organization as organization


[docs]@dataclass class HourlyInterval: """ An hourly interval causes a :class:`.ConnectionSchedule` to execute at a specific minute every hour. Attributes ---------- minute : int The minute of the hour to execute at, between 0 and 59 """ minute: int def serialize(self) -> dict: return { "hourly": { "minute": self.minute, } }
[docs]@dataclass class DailyInterval(HourlyInterval): """ A DailyInterval interval causes a :class:`.ConnectionSchedule` to execute at a specific minute and hour each day Attributes ---------- minute : int The minute of the hour to execute at, between 0 and 59 hour : int The hour of the day to execute at, between 0 and 23 """ hour: int def serialize(self) -> dict: result = super().serialize()["hourly"] result["hour"] = self.hour return {"daily": result}
[docs]@dataclass class WeeklyInterval(DailyInterval): """ A WeelyInterval interval causes a :class:`.ConnectionSchedule` to execute on a specific day of the week, at a specific minute+hour, every week. Attributes ---------- minute : int The minute of the hour to execute at, between 0 and 59 hour : int The hour of the day to execute at, between 0 and 23 dayOfWeek: int The day of the week beginning on Sunday, between 0 and 6 """ dayOfWeek: int def serialize(self) -> dict: result = super().serialize()["daily"] result["dayOfWeek"] = self.dayOfWeek return {"weekly": result}
[docs]@dataclass class MonthlyInterval(DailyInterval): """ A MonthlyInterval interval causes a :class:`.ConnectionSchedule` to execute on a specific day of the month, at a specific minute+hour, every month. Attributes ---------- minute : int The minute of the hour to execute at, between 0 and 59 hour : int The hour of the day to execute at, between 0 and 23 dayOfMonth : int The day of the week to execute at, beginning on Sunday, between 1 and 31, or "-1" for the last day of each month """ dayOfMonth: int def serialize(self) -> dict: result = super().serialize()["daily"] result["dayOfMonth"] = self.dayOfMonth return {"monthly": result}
[docs]@dataclass class YearlyInterval(MonthlyInterval): """ A MonthlyInterval interval causes a :class:`.ConnectionSchedule` to execute on a specific day of a specific month, at a specific minute+hour, every year. Attributes ---------- minute : int The minute of the hour to execute at, between 0 and 59 hour : int The hour of the day to execute at, between 0 and 23 dayOfMonth : int The day of the week to execute at, beginning on Sunday, between 1 and 31, or "-1" for the last day of each month month : int The month of the year to execute at, between 1 and 12 """ month: int def serialize(self) -> dict: result = super().serialize()["monthly"] result["month"] = self.month return {"yearly": result}
def _deserializeInterval( data: dict ) -> Union[HourlyInterval, DailyInterval, WeeklyInterval, MonthlyInterval, YearlyInterval]: if "yearly" in data: return YearlyInterval(data["yearly"]["minute"], data["yearly"]["hour"], data["yearly"]["dayOfMonth"], data["yearly"]["month"]) if "monthly" in data: return MonthlyInterval(data["monthly"]["minute"], data["monthly"]["hour"], data["monthly"]["dayOfMonth"]) if "weekly" in data: return WeeklyInterval(data["weekly"]["minute"], data["weekly"]["hour"], data["weekly"]["dayOfWeek"]) if "daily" in data: return DailyInterval(data["daily"]["minute"], data["daily"]["hour"]) if "hourly" in data: return HourlyInterval(data["hourly"]["minute"]) raise CatalogException(message="Cannot deserialize schedule")
[docs]@dataclass class ConnectionSchedule(): """ A :class:`.ConnectionSchedule` describes the frequency with which to reingest ingested data, or re-analyze virtualized data Attributes __________ interval: HourlyInterval | DailyInterval | WeeklyInterval | MonthlyInterval | YearlyInterval The interval that this schedule represents timezone: str The timezone in which to interpret times in the `interval` """ interval: Union[HourlyInterval, DailyInterval, WeeklyInterval, MonthlyInterval, YearlyInterval] timezone: str def serialize(self) -> dict: res = { "timezone": self.timezone, } res.update(self.interval) return res @classmethod def deserialize(cls, data: dict) -> None: return ConnectionSchedule(timezone=data["timezone"], interval=_deserializeInterval(data))
def _deserialize_connection_schedules( data: List[dict]) -> Optional[List[ConnectionSchedule]]: if data is None: return None return list(map(lambda d: ConnectionSchedule.deserialize(d), data)) @Entity([ Property("id", str, serialize=True), Property("source_id", str, relation="tdw_catalog.source.Source"), Property("user_id", str), Property("label", str, writable=True), Property("description", Optional[str], writable=True), Property("portal", ConnectionPortalType, writable=True), Property("url", str, writable=True), Property("warehouse", Optional[str], writable=True), Property("credential_id", Optional[str], relation="tdw_catalog.credential.Credential", writable=True), Property("disabled", Optional[bool], writable=True), Property("created_at", datetime), Property("updated_at", datetime) ]) class _Connection(EntityBase, _SourceRelation, _CredentialRelation): """ :class:`._Connection`\\ s are used to attach data to a :class:`.Dataset`, describing the mechanism and necessary credentials for accessing said data. Data can be ingested via a :class:`._Connection`, pulled from an uploaded file, or a remote location such as a cloud storage bucket. Data can also be virtualized via a :class:`._Connection`, accessed from a remote location without being copied into the platform. Attributes ---------- id : str :class:`._Connection`\\ 's unique id source_id : str The unique ID of the :class:`.Source` to which this :class:`._Connection` belongs source : Source The :class:`.Source` associated with this :class:`._Connection`. A :class:`.Source` or ``source_id`` can be provided but not both. user_id : str The unique :class:`.User` ID of the user who created this :class:`._Connection` label : str The descriptive label for this :class:`._Connection` description : Optional[str] = None An optional extended description for this :class:`._Connection` portal : ConnectionPortalType The method of data access employed by this :class:`._Connection` url : str A canonical URL that points to the location of data resources within the portal warehouse : Optional[str] Virtualized datasets created using this :class:`._Connection` will always access data from this :class:`.Warehouse` (must be suplied for virtualization). Non-virtualized datasets created using this :class:`._Connection` will ingest to this :class:`.Warehouse` by default (can be overriden at ingest time). default_schema: Optional[str] The schema to search for tables and views when this :class:`._Connection` is used for data virtualization. This field must be empty for ingestion-oriented :class:`._Connection`\\ s, and is optional for virtualization-oriented ones. credential_id : Optional[str] The :class:`.Credential` ID that should be used along with the portal to access :class:`.Dataset`\\ s when ingesting. Omitted when virtualizing. credential : Optional[credential.Credential] The :class:`.Credential` associated with this :class:`._Connection`. Omitted when virtualizing. A :class:`.Credential` or ``credential_id`` can be provided but not both. ingest_schedules : Optional[List[ConnectionSchedule]] Optional :class:`.ConnectionSchedule`\\ s which, when specified, indicate the frequency with which to reingest ingested data, or re-analyze virtualized data. Specific :class:`.Dataset`\\ s using this :class:`._Connection` may override this set of :class:`.ConnectionSchedule`\\ s. disabled : Optional[bool] When true, disables the schedule on this :class:`._Connection`. The :class:`._Connection` itself can still be used for manual ingestion or data virtualization. created_at : datetime The datetime at which this :class:`._Connection` was created updated_at : datetime The datetime at which this :class:`._Connection` was last updated """ id: str source_id: str source: 'source.Source' user_id: str label: str description: Optional[str] portal: ConnectionPortalType url: str warehouse: Optional[str] credential_id: Optional[str] credential: Optional['credential.Credential'] created_at: datetime updated_at: datetime def __str__(self) -> str: return f'<Connection id={self._id} label={self.label} portal={self.portal}>' @classmethod def get(cls, client, id: str): """ Retrieve a :class:`._Connection` Parameters ---------- client : Catalog The :class:`.Catalog` client to use to get the :class:`._Connection` id : str The unique ID of the :class:`._Connection` Returns ------- _Connection The :class:`._Connection` associated with the given ID Raises ------ CatalogInternalException If call to the :class:`.Catalog` server fails CatalogNotFoundException If the :class:`._Connection` with the supplied ID could not be found CatalogPermissionDeniedException If the caller is not allowed to retrieve this :class:`._Connection` """ try: res = client._get_connection(id=id) if res["portal"] == ConnectionPortalType.EXTERNAL: return VirtualizationConnection(client, **res) else: return IngestionConnection(client, **res) except Exception as e: err = _raise_error(e, "Unable to fetch Connection {}".format(id)) def save(self) -> None: """ Update this :class:`._Connection`, saving any changes to its fields Raises ------ CatalogPermissionDeniedException If the caller is not allowed to update this :class:`._Connection` CatalogNotFoundException If the :class:`._Connection` no longer exists CatalogException If call to the :class:`.Catalog` server fails """ try: res = self._client._update_connection(**self.serialize()) self.deserialize(res) except Exception as e: raise _convert_error(e) def delete(self) -> None: """ Delete this :class:`._Connection`. This :class:`._Connection` object should not be used after `delete()` has successfully returned Raises ------ CatalogPermissionDeniedException If the caller is not allowed to delete this :class:`._Connection` CatalogNotFoundException If the :class:`._Connection` no longer exists CatalogException If call to the :class:`.Catalog` server fails """ try: self._client._delete_connection(id=self.id) except Exception as e: raise _convert_error(e)
[docs]@Entity([ Property("ingest_schedules", Optional[List[ConnectionSchedule]], writable=True, deserialize=_deserialize_connection_schedules), ]) class IngestionConnection(_Connection): """ :class:`.IngestionConnection`\\ s are used to attach ingested data to a :class:`.Dataset`, describing the mechanism and necessary credentials for accessing said data. Data is ingested via an :class:`.IngestionConnection`: pulled from an uploaded file, or a remote location such as a cloud storage bucket. Attributes ---------- id : str :class:`.IngestionConnection`\\ 's unique id source_id : str The unique ID of the :class:`.Source` to which this :class:`.IngestionConnection` belongs source : Source The :class:`.Source` associated with this :class:`.IngestionConnection`. A :class:`.Source` or ``source_id`` can be provided but not both. user_id : str The unique :class:`.User` ID of the user who created this :class:`.IngestionConnection` label : str The descriptive label for this :class:`.IngestionConnection` description : Optional[str] = None An optional extended description for this :class:`.IngestionConnection` portal : ConnectionPortalType The method of data access employed by this :class:`.IngestionConnection` url : str A canonical URL that points to the location of data resources within the portal warehouse : Optional[str] :class:`.Dataset`\\ s created using this :class:`.IngestionConnection` will ingest to this :class:`.Warehouse` by default (can be overriden at ingest time). credential_id : Optional[str] The :class:`.Credential` ID that should be used along with the portal to access :class:`.Dataset`\\ s when ingesting. credential : Optional[credential.Credential] The :class:`.Credential` associated with this :class:`.IngestionConnection`. Omitted when virtualizing. A :class:`.Credential` or ``credential_id`` can be provided but not both. ingest_schedules : Optional[List[ConnectionSchedule]] Optional :class:`.ConnectionSchedule`\\ s which, when specified, indicate the frequency with which to reingest ingested data. Specific :class:`.Dataset`\\ s using this :class:`.IngestionConnection` may override this set of :class:`.ConnectionSchedule`\\ s. disabled : Optional[bool] When true, disables the schedule on this :class:`.IngestionConnection`. The :class:`.IngestionConnection` itself can still be used for manual ingestion or data virtualization. created_at : datetime The datetime at which this :class:`.IngestionConnection` was created updated_at : datetime The datetime at which this :class:`.IngestionConnection` was last updated """ ingest_schedules: Optional[List[ConnectionSchedule]]
[docs]@Entity([ Property("default_schema", Optional[str], writable=True), Property("ingest_schedules", Optional[List[ConnectionSchedule]], display_key="metrics_collection_schedules", writable=True, deserialize=_deserialize_connection_schedules), ]) class VirtualizationConnection(_Connection): """ :class:`.VirtualizationConnection`\\ s are used to attach virtualized data to a :class:`.Dataset`, describing the mechanism and necessary credentials for accessing said data. Data is accessed from a remote location without being copied into the platform. Attributes ---------- id : str :class:`.IngestionConnection`\\ 's unique id source_id : str The unique ID of the :class:`.Source` to which this :class:`.IngestionConnection` belongs source : Source The :class:`.Source` associated with this :class:`.IngestionConnection`. A :class:`.Source` or ``source_id`` can be provided but not both. user_id : str The unique :class:`.User` ID of the user who created this :class:`.IngestionConnection` label : str The descriptive label for this :class:`.IngestionConnection` description : Optional[str] = None An optional extended description for this :class:`.IngestionConnection` portal : ConnectionPortalType The method of data access employed by this :class:`.IngestionConnection` url : str A canonical URL that points to the location of data resources within the portal warehouse : Optional[str] Virtualized datasets created using this :class:`.IngestionConnection` will always access data from this :class:`.Warehouse` (must be suplied for virtualization). Non-virtualized datasets created using this :class:`.IngestionConnection` will ingest to this :class:`.Warehouse` by default (can be overriden at ingest time). credential_id : Optional[str] The :class:`.Credential` ID that should be used along with the portal to access :class:`.Dataset`\\ s when ingesting. Omitted when virtualizing. credential : Optional[credential.Credential] The :class:`.Credential` associated with this :class:`.IngestionConnection`. Omitted when virtualizing. A :class:`.Credential` or ``credential_id`` can be provided but not both. default_schema: str The schema to search for tables and views metrics_collection_schedules : Optional[List[ConnectionSchedule]] Optional :class:`.ConnectionSchedule`\\ s which, when specified, indicate the frequency with which to re-analyze virtualized data. Specific :class:`.Dataset`\\ s using this :class:`.VirtualizationConnection` may override this set of :class:`.ConnectionSchedule`\\ s. disabled : Optional[bool] When true, disables the schedule on this :class:`.IngestionConnection`. The :class:`.IngestionConnection` itself can still be used for manual ingestion or data virtualization. created_at : datetime The datetime at which this :class:`.IngestionConnection` was created updated_at : datetime The datetime at which this :class:`.IngestionConnection` was last updated """ default_schema: Optional[str] metrics_collection_schedules: Optional[List[ConnectionSchedule]]