from dataclasses import dataclass from typing import List, Optional, Dict, Any from marshmallow import EXCLUDE from external_api.base.clients.client import FivetranApiClient from external_api.fivetran.fivetran_services_configs import services_configs from config import FIVETRAN_TIMEFRAME_MONTH, FIVETRAN_WEBHOOK_SECRET HIDE_SETUP_GUIDE = True @dataclass class FivetranBaseResponse: code: str message: Optional[str] data: Any @dataclass class Task: code: str message: str @dataclass class Warning: code: str message: str @dataclass class Status: tasks: List[Task] warnings: List[Warning] schema_status: str update_state: str setup_state: str sync_state: str is_historical_sync: bool rescheduled_for: Optional[str] class Meta: unknown = EXCLUDE @dataclass class ConnectCard: token: str uri: str @dataclass class SetupTest: title: str status: str message: str details: Dict[str, str] @dataclass class ConnectCardConfig: redirect_uri: str hide_setup_guide: bool @dataclass class ConnectorResponse: id: str service: str schema: str paused: bool status: Status daily_sync_time: Optional[str] succeeded_at: Optional[str] connect_card: Optional[ConnectCard] sync_frequency: Optional[int] pause_after_trial: Optional[bool] group_id: str connected_by: str setup_tests: Optional[List[SetupTest]] source_sync_details: Optional[Dict[str, str]] service_version: Optional[int] created_at: str failed_at: Optional[str] schedule_type: str connect_card_config: Optional[ConnectCardConfig] config: Optional[Any] class Meta: unknown = EXCLUDE @dataclass class FivetranConnectorCreateBaseResponse(FivetranBaseResponse): data: ConnectorResponse class Meta: unknown = EXCLUDE @dataclass class ConnectorsList: items: List[ConnectorResponse] nextCursor: Optional[str] @dataclass class FivetranConnectorsListBaseResponse(FivetranBaseResponse): data: ConnectorsList @dataclass class WebhookCreateResponse: id: str type: str url: str secret: Optional[str] created_at: str created_by: str group_id: str active: bool events: List[str] @dataclass class FivetranwebhookBaseResponse(FivetranBaseResponse): data: WebhookCreateResponse @dataclass class GenerateConnectCardResponse: connect_card: ConnectCard connector_id: str connect_card_config: ConnectCardConfig @dataclass class FivetranGenerateConnectCardBaseResponse(FivetranBaseResponse): data: GenerateConnectCardResponse @dataclass class FivetranWebhookCreateBaseResponse(FivetranBaseResponse): data: Optional[WebhookCreateResponse] class FivetranClient: http_client: FivetranApiClient def __init__(self, client: FivetranApiClient) -> None: self.http_client = client async def get_connectors(self, group_id: str) -> List[ConnectorsList]: endpoint = "/groups/{}/connectors".format(group_id) response = await self.http_client.get(endpoint, response_type=FivetranConnectorsListBaseResponse) return response.data async def get_connector_by_id(self, connector_id: str) -> ConnectorResponse: endpoint = "/connectors/{}".format(connector_id) response = await self.http_client.get(endpoint, response_type=FivetranConnectorCreateBaseResponse) return response.data async def generate_connect_card(self, connector_id: str, redirect_uri: str) -> str: params = { "connect_card_config": { "redirect_uri": redirect_uri, "hide_setup_guide": HIDE_SETUP_GUIDE } } endpoint = f"/connectors/{connector_id}/connect-card" response = await self.http_client.post( endpoint, payload=params, response_type=FivetranGenerateConnectCardBaseResponse ) return response.data.connect_card.uri async def create_connector(self, group_id: str, platform: str, name: str, redirect_uri: str) -> ConnectorResponse: params = { "group_id": group_id, "service": platform, "run_setup_tests": False, "connect_card_config": { "redirect_uri": redirect_uri, "hide_setup_guide": HIDE_SETUP_GUIDE }, "config": { "schema": name, "timeframe_months": FIVETRAN_TIMEFRAME_MONTH, **services_configs.get(platform, {}), "conversion_window_size": 30, } } endpoint = "/connectors" response = await self.http_client.post( endpoint, payload=params, response_type=FivetranConnectorCreateBaseResponse ) return response.data async def get_webhooks(self, group_id: str): pass async def create_webhook(self, group_id: str, events: List, url: str): params = { "url": url, "active": True, "events": events, # "secret": FIVETRAN_WEBHOOK_SECRET } endpoint = f"/webhooks/group/{group_id}" webhook_response = await self.http_client.post( endpoint, payload=params, response_type=FivetranWebhookCreateBaseResponse ) return True async def pause_connector(self, connector_external_id: str): pass