"""iTunes Hides Workflow.""" from garcon.param import StaticParam 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 FlowLoadRawMixinSF from feed_ingestion.flows.itunes_hides import config from feed_ingestion.flows.itunes_hides import tasks from feed_ingestion.tasks import feed_status_tasks from feed_ingestion.tasks import load_raw_table_tasks_sf from feed_ingestion.tasks import s3_tasks class Flow(FlowBase, FlowConfigMixin, FlowLoadRawMixinSF): """iTunes Hides Flow class. This flow downloads iTunes Hides data and loads to a itunes hides staging tables. """ def __init__(self): """Initialize a iTunes Hides workflow.""" super(Flow, self).__init__(config.feed_name, config.feed_version) def decider(self, schedule): """Orchestrate a iTunes Hides workflow. Args: schedule (callable): The scheduler method. """ bootstrap = schedule('bootstrap', self.bootstrap) if bootstrap.result.get('bootstrap.stop') is True: return check_files_on_s3 = schedule( 'check_files_on_s3', self.check_files_on_s3, requires=[bootstrap]) if check_files_on_s3.result.get('check_files_on_s3.stop') is True: return grab_drop_files = schedule( 'grab_drop_files', self.grab_drop_files, requires=[check_files_on_s3]) process_drop_files = schedule( 'process_drop_files', self.process_drop_files, requires=[grab_drop_files]) create_temp_staging_raw_table = schedule( 'create_temp_staging_raw_table', self.create_temp_staging_raw_table, requires=[process_drop_files]) load_temp_staging_raw_table = schedule( 'load_temp_staging_raw_table', self.load_temp_staging_raw_table, requires=[create_temp_staging_raw_table]) load_snapshot_table = schedule( 'load_snapshot_table', self.load_snapshot_table, requires=[load_temp_staging_raw_table] ) load_staging_raw_table = schedule( 'load_staging_raw_table', self.load_staging_raw_table, requires=[load_snapshot_table]) drop_temp_staging_table = schedule( 'drop_temp_staging_table', self.drop_temp_staging_table, requires=[load_staging_raw_table]) cleanup_s3 = schedule( 'cleanup_s3', self.cleanup_s3, requires=[drop_temp_staging_table]) schedule( 'set_status_to_ingested', self.set_status_to_ingested, requires=[cleanup_s3]) @property def bootstrap(self): """Bootstrap initial configuration.""" return self.create( name='bootstrap', tasks=base.SyncRunner( tasks.bootstrap.fill( namespace='bootstrap', date='context_date', reload='reload'))) @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.download_path'))) @property def grab_drop_files(self): """Move file from drop (downloads) folder to archive folder on S3.""" return self.create( name='grab_drop_files', tasks=base.SyncRunner( s3_tasks.copy_files.fill( namespace='grab_drop_files', s3_archive_path='bootstrap.archive_path', s3_download_path='bootstrap.download_path', source_files_dict='check_files_on_s3.source_files_dict', need_all_files=StaticParam(True)))) @property def cleanup_s3(self): """Cleanup S3 in order to achieve idempotency.""" return self.create( name='cleanup_s3', tasks=base.SyncRunner( tasks.remove_files_from_path.fill( namespace='cleanup_s3', download_path='bootstrap.download_path', date='bootstrap.date', source_files_dict='check_files_on_s3.source_files_dict', ))) @property def process_drop_files(self): """Process drop files.""" return self.create( name='process_drop_files', tasks=base.SyncRunner( tasks.process_drop_files.fill( namespace='process_drop_files', feed_name='bootstrap.feed_name', date='bootstrap.date', s3_archive_path='bootstrap.archive_path', s3_preprocessed_path='bootstrap.preprocessed_path', source_files_dict='grab_drop_files.source_files_dict'))) @property def create_temp_staging_raw_table(self): """Create temp staging raw table.""" return self.create( name='create_temp_staging_raw_table', generators=[self.temp_staging_tables_generator], tasks=base.SyncRunner( load_raw_table_tasks_sf.create_temp_staging_raw_table.fill( namespace='create_temp_staging_raw_table', date='bootstrap.date', sfdb_params='sfdb_params', secrets_path='bootstrap.secrets_path', feed_name='bootstrap.feed_name', temp_staging_raw_table='temp_staging_raw_table'))) @property def load_temp_staging_raw_table(self): """Load temp staging raw table.""" return self.create( name='load_temp_staging_raw_table', generators=[self.temp_staging_tables_generator], tasks=base.SyncRunner( load_raw_table_tasks_sf.load_temp_staging_raw_table.fill( namespace='load_temp_staging_raw_table', date='bootstrap.date', sfdb_params='sfdb_params', feed_name='bootstrap.feed_name', secrets_path='bootstrap.secrets_path', kwargs='kwargs', key_dir='key_dir', temp_staging_raw_table='temp_staging_raw_table'))) @property def load_snapshot_table(self): """Load snapshot table.""" return self.create( name='load_snapshot_table', tasks=base.SyncRunner( tasks.load_snapshot_table.fill( namespace='load_snapshot_table', date='bootstrap.date', sfdb_params='sfdb_params', feed_name='bootstrap.feed_name', secrets_path='bootstrap.secrets_path', kwargs='kwargs', temp_staging_raw_table='bootstrap.temp_staging_raw_table', snapshot_table='bootstrap.snapshot_table', snapshots_amount_to_keep='bootstrap.snapshots_amount'))) @property def drop_temp_staging_table(self): """Drop the temporary staging tables.""" return self.create( name='drop_temp_staging_table', generators=[self.temp_staging_tables_generator], tasks=base.SyncRunner( load_raw_table_tasks_sf.drop_temp_staging_raw_table.fill( namespace='drop_temp_staging_table', feed_name='bootstrap.feed_name', secrets_path='bootstrap.secrets_path', sfdb_params='sfdb_params', temp_staging_raw_table='temp_staging_raw_table'))) def temp_staging_tables_generator(self, context): """Generate parameters for temporary staging tables. Used by the create_temp_staging_raw_table, load_temp_staging_raw_table activity and drop_temp_staging_table. Args: context (dict): The current context. Yields: dict: Dictionary of temporary staging table names. """ yield dict( temp_staging_raw_table=context['bootstrap.temp_staging_raw_table'], key_dir=context['bootstrap.preprocessed_path'])