from typing import List from delphi_api.bigtable import BigTableModel from delphi_api.const import ENABLE_FAKE_DATA from delphi_api.errors.descriptions import ITEM_NOT_FOUND from delphi_api.utils import Models from delphi_api.v3.constants import DSP_CHARTMETRIC, ENABLED_DSPS from delphi_api.v3.data_models.bigtable.chartmetric import ChartmetricArtist from delphi_api.v3.data_models.bigtable.row_key_builder import RowKeyBuilder, RowKeyGroupType from delphi_api.v3.data_models.postgres_db import Artist, db from delphi_api.v3.data_models.schemas.generics import FollowerSchema from delphi_api.v3.data_models.schemas.models import ArtistSimpleSchema from delphi_api.v3.enums import RowKeyAgg from delphi_api.v3.view_models.fake_utils import FakeUtils from delphi_api.v3.view_models.generic_dsp import GenericDspViewModel from delphi_api.v3.view_models.params import Params from delphi_api.v3.view_models.query_builder import QueryBuilder class ArtistsViewModel: CHARTMETRIC_MODELS = { DSP_CHARTMETRIC: ChartmetricArtist, } ENABLED_CHARTMETRIC_MODELS = {k: v for k, v in CHARTMETRIC_MODELS.items() if k in ENABLED_DSPS} @staticmethod def _get_fake_followers(params: Params) -> list: return FakeUtils.get_fake_artist_followers(params) @classmethod def get_one(cls, params: dict): """Get a single artist's metadata from postgres""" params = Params(**params) result = db.session.query(Artist).get_or_404(params.artist_id, description=ITEM_NOT_FOUND) return ArtistSimpleSchema().dump(result) @classmethod def get_many(cls, params: dict): """Get multiple artists' metadata from postgres""" params = Params(**params) q = db.session.query(Artist) q = QueryBuilder.or_filters_from_params(q, params, parent=Artist) q = QueryBuilder.add_sort_clause(q, params, parent=Artist) q = QueryBuilder.add_query_limit_offset(q, params) return ArtistSimpleSchema(many=True).dump(q.all()) @classmethod def get_followers(cls, params: dict): """Get a single artist's followers data from bigtable (chartmetric data)""" params = Params(**params) followers = cls.get_followers_data(params) items = FollowerSchema(many=True).dump(followers) base_key = 'artist_id' grouped_data = Models.aggregate_generic(items, base_key, group_by=params.group_by) result = Models.flatten_generic(grouped_data) result = QueryBuilder.sort_results(result, params) result = QueryBuilder.limit_offset_results(result, params) return FollowerSchema(many=True).dump(result) @classmethod def load_additional_params_followers(cls, params: Params): return params @classmethod def get_followers_data(cls, params: Params) -> List[BigTableModel]: """Get the underlying followers data from underlying data sources""" if ENABLE_FAKE_DATA: return cls._get_fake_followers(params) item_keys = RowKeyBuilder.get_row_keys(params, RowKeyGroupType.CHARTMETRIC, RowKeyAgg.DAILY) base_key = 'artist_id' model = GenericDspViewModel(params, data_model=ChartmetricArtist, base_key_name=base_key) return model.bigtable_load_results(item_keys).results