""" Membran Ingestion Workflow. Ingest data from Membran. """ from garcon.param import StaticParam from garcon_contrib.dynamo_feed_status import garcon_feed_status from snowflake_connector.etl_connector import SQLLoader from feed_ingestion.flows import base from feed_ingestion.flows.physical_warehouse_reports import config from feed_ingestion.flows.physical_warehouse_reports import tasks from feed_ingestion.flows.physical_warehouse_reports.stage_loader \ import PhysicalWarehouseReportsSL from feed_ingestion.tasks import overall_status_tasks class Flow(base.FlowBase, base.FlowConfigMixin, base.FlowLoadRawMixinSF): """Class representing the workflow.""" def __init__(self): """Initialize flow object.""" super(Flow, self).__init__(feed_name=config.feed_name, version='3.0') self.timeout = 60 * 60 * 5 # set "Execution Start To Close Timeout" def decider(self, schedule, context): """Activity decider. Args: schedule (callable): The scheduler method. """ # context_date has to be forcibly updated with current date! # otherwise data will be corrupted - we don't have access to history # reload=True is mandatory for use! # otherwise first day execution on yesterday file won't allow data # refresh when today file becomes updated bootstrap = schedule('bootstrap', self.bootstrap) # Stop flow if feed already ingested if bootstrap.result.get('bootstrap.stop'): return grab_drop_files_s3 = schedule( 'grab_drop_files_s3', self.grab_drop_files_s3, requires=[bootstrap]) if grab_drop_files_s3.result.get('grab_drop_files_s3.stop'): return # Status set to DOWNLOADED if files are present, else NOT_AVAILABLE set_status_to_downloaded = schedule( 'set_status_to_downloaded', self.set_status_to_downloaded, requires=[grab_drop_files_s3]) if bootstrap.result.get('bootstrap.use_s3'): next_steps_requires = [set_status_to_downloaded] else: gzip_and_put = schedule( 'gzip_and_put', self.gzip_and_put, requires=[grab_drop_files_s3]) next_steps_requires = [gzip_and_put] load_staging_raw_table = schedule( 'load_staging_raw_table', self.load_staging_raw_table, requires=next_steps_requires) # Status updated to POPULATED_RAW_TABLE schedule( 'set_status_to_populated_raw_table', self.set_status_to_populated_raw_table, requires=[load_staging_raw_table]) @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', use_s3='use_s3', date_format='date_format'))) @property def grab_drop_files_s3(self): """Grab files and upload to archive bucket on S3.""" return self.create( name='grab_drop_files_s3', tasks=base.AsyncRunner( tasks.grab_drop_files_s3.fill( namespace='grab_drop_files_s3', feed_name='bootstrap.feed_name', date='bootstrap.date', drop_file_name='bootstrap.drop_file_name', source_bucket_name='bootstrap.s3_drop_bucket', source_path='bootstrap.source_path', destination_arch_full_path='bootstrap.s3_archive_bucket', ))) @property def gzip_and_put(self): """Gzip drop file and then place to temp path.""" return self.create( name='gzip_and_put', tasks=base.SyncRunner( tasks.gzip_and_put.fill( namespace='gzip_and_put', feed_name='bootstrap.feed_name', date='bootstrap.date', source_s3_path='bootstrap.s3_archive_bucket', target_s3_path='bootstrap.s3_temp_staging_raw_bucket', drop_file_name='bootstrap.drop_file_name', ))) load_staging_raw_table = PhysicalWarehouseReportsSL.load_activity( feed_name='bootstrap.feed_name', secrets_path=config.secrets_path, sql_loader=SQLLoader(__file__), requirements=dict( date='bootstrap.date', feed_name='bootstrap.feed_name', source_files_dict='bootstrap.source_files_dict', s3_dir_path='bootstrap.s3_temp_staging_raw_bucket', staging_raw_table_name='bootstrap.staging_raw_table', date_format='bootstrap.date_format')) @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))))