""" Deezer Marketshare Workflow. Ingest Deezer marketshare data into marketshare table in Snowflake. """ from garcon.param import StaticParam from snowflake_connector.etl_connector import SQLLoader from feed_ingestion.flows import base from feed_ingestion.flows.base import FlowBase from feed_ingestion.flows.base import FlowConfigMixin from feed_ingestion.flows.base import FlowLoadMarketshareMixinSF from feed_ingestion.flows.base import FlowLoadRawMixinSF from feed_ingestion.flows.deezer_marketshare import config from feed_ingestion.flows.deezer_marketshare import stage_loader from feed_ingestion.flows.deezer_marketshare import tasks from feed_ingestion.tasks import date_tasks, deezer_tasks from feed_ingestion.tasks import feed_status_tasks from feed_ingestion.tasks import garcon_feed_status from feed_ingestion.tasks import overall_status_tasks class Flow( FlowBase, FlowConfigMixin, FlowLoadRawMixinSF, FlowLoadMarketshareMixinSF): """Deezer Marketshare Flow class. This flow downloads Deezer marketshare data and loads to a main_market_share. """ def __init__(self): """Initialize an Deezer Marketshare workflow.""" super(Flow, self).__init__(config.feed_name, config.feed_version) def decider(self, schedule): """Orchestrate an Deezer Marketshare workflow. Args: schedule (callable): The scheduler method. """ get_first_day_of_month = schedule( 'get_first_day_of_month', self.get_first_day_of_month) bootstrap = schedule( 'bootstrap', self.bootstrap, requires=[get_first_day_of_month]) requires = [bootstrap] fetch_from_drop_location = schedule( 'fetch_from_drop_location', self.fetch_from_drop_location, requires=requires) if fetch_from_drop_location.result.get( 'fetch_from_drop_location.stop'): return set_status_to_downloaded = schedule( 'set_status_to_downloaded', self.set_status_to_downloaded, requires=[fetch_from_drop_location]) unzip_and_clean = schedule( 'unzip_and_clean', self.unzip_and_clean, requires=[set_status_to_downloaded]) load_staging_raw_table = schedule( 'load_staging_raw_table', self.load_staging_raw_table, requires=[unzip_and_clean]) set_status_to_populated_raw_table = schedule( 'set_status_to_populated_raw_table', self.set_status_to_populated_raw_table, requires=[load_staging_raw_table]) load_marketshare_table = schedule( 'load_market_share_table', self.load_marketshare_table, requires=[set_status_to_populated_raw_table]) mark_ingested_files = schedule( 'mark_ingested_files', self.mark_ingested_files, requires=[load_marketshare_table]) schedule( 'set_status_to_ingested', self.set_status_to_ingested, requires=[mark_ingested_files], ) @property def get_first_day_of_month(self): """Get the first day of the month of date.""" return self.create( name='get_first_day_of_month', tasks=base.SyncRunner( date_tasks.get_first_day_of_month.fill( namespace='get_first_day_of_month', date='context_date'))) @property def bootstrap(self): """Bootstrap initial configuration.""" return self.create( name='bootstrap', tasks=base.SyncRunner( tasks.bootstrap.fill( namespace='bootstrap', date='get_first_day_of_month.date', reload='reload' ))) @property def fetch_from_drop_location(self): """Move file from Zephir to drop bucket.""" return self.create( name='fetch_from_drop_location', tasks=base.SyncRunner( tasks.fetch_from_drop_location.fill( namespace='fetch_from_drop_location', feed_name='bootstrap.feed_name', date='bootstrap.date', source_path='bootstrap.zephir_path', target_s3_path='bootstrap.s3_archive_path', filename_pattern='bootstrap.zephir_zip_pattern' ))) @property def check_files_on_s3(self): """Check if there are some new files in s3_download_path.""" return self.create( name='check_files_on_s3', tasks=base.SyncRunner( feed_status_tasks.check_files_on_s3.fill( namespace='check_files_on_s3', feed_name='bootstrap.feed_name', date='bootstrap.date', file_pattern='bootstrap.file_pattern', s3_download_path='bootstrap.s3_download_path'))) @property def unzip_and_clean(self): """Unzip drop file and clean then place to temp path.""" return self.create( name='unzip_and_clean', tasks=base.SyncRunner( deezer_tasks.unzip_and_clean.fill( namespace='unzip_and_clean', feed_name='bootstrap.feed_name', date='bootstrap.date', source_s3_path='bootstrap.s3_archive_path', target_s3_path='bootstrap.s3_temp_staging_raw_bucket', drop_file_name='bootstrap.drop_file_name', source_files_dict='fetch_from_drop_location.' 'source_files_dict', use_drop_file=StaticParam(True) ))) load_staging_raw_table = stage_loader.DeezerMSSL.load_activity( feed_name=config.feed_name, secrets_path=config.secrets_path, sql_loader=SQLLoader(__file__), requirements=dict( date='bootstrap.date', feed_name='bootstrap.feed_name', source_files_dict='unzip_and_clean.source_files_dict', s3_dir_path='bootstrap.s3_temp_staging_raw_bucket', staging_raw_table_name='bootstrap.staging_raw_table', sfdb_params='sfdb_params' ) ) @property def set_status_to_downloaded(self): """Set overall feed status to DOWNLOADED.""" return self.create( name='set_status_to_downloaded', tasks=base.SyncRunner( overall_status_tasks.set_overall_status.fill( namespace='set_status_to_downloaded', feed_name='bootstrap.feed_name', date='bootstrap.date', status=StaticParam( garcon_feed_status.STATUS_DOWNLOADED)))) @property def set_status_to_populated_raw_table(self): """Set overall feed status to POPULATED_RAW_TABLE.""" return self.create( name='set_status_to_populated_raw_table', tasks=base.SyncRunner( overall_status_tasks.set_overall_status.fill( namespace='set_status_to_populated_raw_table', feed_name='bootstrap.feed_name', date='bootstrap.date', status=StaticParam( garcon_feed_status.STATUS_POPULATED_RAW_TABLE)))) @property def mark_ingested_files(self): """Put list of ingested files in DynamoDB.""" return self.create( name='mark_ingested_files', tasks=base.SyncRunner( feed_status_tasks.mark_ingested_files.fill( namespace='mark_ingested_files', feed_name='bootstrap.feed_name', date='bootstrap.date', source_files_dict='unzip_and_clean.source_files_dict' ))) @property def set_status_to_ingested(self): """Set overall feed status to INGESTED.""" return self.create( name='set_status_to_ingested', tasks=base.SyncRunner( overall_status_tasks.set_overall_status.fill( namespace='set_status_to_ingested', feed_name='bootstrap.feed_name', date='bootstrap.date', status=StaticParam( garcon_feed_status.STATUS_INGESTED, ), ), ), )