""" Integration with Digital Service Provider's API. DSP is a dsp-api app: https://github.com/filtr/dsp-api. """ import requests from datetime import date, datetime, timedelta from flask import current_app as app from typing import Dict, List, Tuple from src.constants.core import VENDORS, Service from src.legacy.core.client_base import BaseInternalAPIClient class DigitalServiceProvider(BaseInternalAPIClient): """Object oriented interface to DSP API. It provides methods for accessing the API, handles preparing HTTP requests, parsing and validating responses, maintaining session etc. """ service_name = Service.DSP_API env_app_key = "DSP_AUTH" env_host_name = "DSP_API" def get_isrc_to_streams_map( self, isrc_list: List[str], vendors_list: List[str], start_date: date, end_date: date, market: str = "" ) -> Dict[str, int]: """Returns summed streams data for all vendors in vendors_list by isrc. Args: isrc_list: list of isrc to get data for. vendors_list: list of vendors to get streams for. start_date: date range start. end_date: date range end. market: market code, empty or '_gl' for global. Returns: Dict[str, int]: dict of isrc with streams data. """ if not isrc_list: return {} tracks_streams_data = self.get_tracks_bulk_streams_data( isrc_list=isrc_list, start_date=start_date, end_date=end_date, vendors=vendors_list, market=market ) isrc_to_streams = {isrc: 0 for isrc in isrc_list} for isrc, streams in tracks_streams_data.items(): isrc_to_streams[isrc] = streams return isrc_to_streams def get_tracks_bulk_streams_data( self, isrc_list: List[str], start_date: date, end_date: date, vendors: List[str], market: str = "" ) -> Dict: """Returns streams values for list of track ISRCs.""" url = app.config["DSP_TRACKS_BULK_STREAMS_URL_V1"] params = { "isrc": isrc_list, "start_date": start_date.isoformat(), "end_date": end_date.isoformat(), "market": market, "vendors": vendors, } request = requests.Request("GET", url, params=params) response = self._send_request(request) return response.get("streams", {}) def get_streams_latest_date(self) -> date: """Returns streams latest date.""" url = app.config["DSP_STREAMS_LATEST_DATE_URL"] request = requests.Request("GET", url) response = self._send_request(request) return datetime.strptime(response["date"], "%Y-%m-%d").date() def get_streams_latest_date_range(self, period: int = 6) -> Tuple[date, date]: """Return tuple of start and end dates. Args: period: range length in days. """ end_date = self.get_streams_latest_date() start_date = end_date - timedelta(period) return start_date, end_date def get_streams_first_date(self, isrc_list: List[str], vendor: str) -> Dict: """Get track's first stream dates. Args: isrc_list: List of track's ISRC. vendor: Vendor name. Returns: ISRC to date mapping. """ isrc_list = [i for i in set(isrc_list) if i] if not isrc_list: return {} url = app.config["DSP_STREAMS_FIRST_DATE_URL"] request = requests.Request("GET", url, params={"isrc": isrc_list, "vendor": vendor}) return self._send_request(request) def get_streams_first_date_any_vendor(self, isrc_list: List[str], vendor: str) -> Dict: """Get track's first stream dates for any vendor. Args: isrc_list: List of track's ISRC. vendor: Vendor name. Returns: ISRC to date mapping. """ if vendor: vendors = [vendor] + [v for v in VENDORS if v != vendor] else: vendors = VENDORS result = {} isrc_to_check = isrc_list for next_vendor in vendors: isrc_date_mapping = self.get_streams_first_date(isrc_to_check, next_vendor) result.update(isrc_date_mapping) isrc_to_check = set(isrc_to_check) - set(result.keys()) if not isrc_to_check: break return result