import datetime import enum from dataclasses import dataclass from typing import Any from owsclient import OwsClient from pydantic import BaseModel, Field class AudienceSharePlatform(enum.StrEnum): META = "META" TIKTOK = "TIKTOK" GOOGLE = "GOOGLE" class AudienceShareStatus(enum.StrEnum): PENDING = "PENDING" PROCESSING = "PROCESSING" FAILED = "FAILED" COMPLETED = "COMPLETED" DELETED = "DELETED" class AudienceShare(BaseModel): id: str platform: AudienceSharePlatform class MetaAudienceShare(BaseModel): audience_id: str = Field(alias="audienceId") audience_external_id: str = Field(alias="audienceExternalId") audience_name: str = Field(alias="audienceName") fans_count: int = Field(alias="fansCount") ad_account_external_id: str = Field(alias="adAccountExternalId") user_access_token: str = Field(alias="userAccessToken") class GoogleAudienceShare(BaseModel): audience_id: str = Field(alias="audienceId") audience_external_id: str = Field(alias="audienceExternalId") user_list_resource: str = Field(alias="userListResource") audience_name: str = Field(alias="audienceName") fans_count: int = Field(alias="fansCount") ad_account_external_id: str = Field(alias="adAccountExternalId") parent_ad_account_external_id: str | None = Field(alias="parentAdAccountExternalId") user_access_token: str = Field(alias="userAccessToken") class TikTokAudienceShare(BaseModel): audience_id: str = Field(alias="audienceId") audience_external_id: str | None = Field(alias="audienceExternalId") audience_name: str = Field(alias="audienceName") fans_count: int = Field(alias="fansCount") ad_account_external_id: str = Field(alias="adAccountExternalId") user_access_token: str = Field(alias="userAccessToken") class TikTokAudience(BaseModel): id: str external_id: str = Field(alias="externalId") name: str fans_count: int = Field(alias="fansCount") created_at: datetime.datetime = Field(alias="createdAt") @dataclass class OwsDmpClient: ows_client: OwsClient service_name = "ows-dmp" def update_audience_share( self, share_id: str, status: AudienceShareStatus, processed_fans: int | None = None, ) -> AudienceShare: data: dict[str, Any] = {"status": status.value} if processed_fans: data["processedFans"] = processed_fans response = self.ows_client.patch( self.service_name, f"/audience-shares/{share_id}", json=data, ) response.raise_for_status() return AudienceShare.model_validate_json(response.content) def get_meta_audience_share(self, share_id: str) -> MetaAudienceShare: response = self.ows_client.get( self.service_name, f"/meta/audience-shares/{share_id}", timeout=60.0 ) response.raise_for_status() return MetaAudienceShare.model_validate_json(response.content) def get_tiktok_audience_share(self, share_id: str) -> TikTokAudienceShare: response = self.ows_client.get( self.service_name, f"/tiktok/audience-shares/{share_id}", timeout=60.0 ) response.raise_for_status() return TikTokAudienceShare.model_validate_json(response.content) def get_google_audience_share(self, share_id: str) -> GoogleAudienceShare: response = self.ows_client.get( self.service_name, f"/google/audience-shares/{share_id}", timeout=60.0 ) response.raise_for_status() return GoogleAudienceShare.model_validate_json(response.content) def update_tiktok_audience_external_id( self, audience_id: str, external_id: str ) -> TikTokAudience: response = self.ows_client.patch( self.service_name, f"/tiktok/audiences/{audience_id}", json={"externalId": external_id}, ) response.raise_for_status() return TikTokAudience.model_validate_json(response.content)