"""collection of configured data pipelines, intended to be invoked from C#""" import time from datetime import datetime as Datetime from typing import Final import sqlalchemy as sql from delta_barth import databases as db from delta_barth.analysis import forecast from delta_barth.constants import DEFAULT_DB_ERR_CODE from delta_barth.errors import STATUS_HANDLER, wrap_result from delta_barth.logging import logger_pipelines as logger from delta_barth.management import SESSION from delta_barth.types import JsonExportResponse, PipelineMetrics def _write_performance_metrics( pipeline_name: str, time_start: int, time_end: int, ) -> PipelineMetrics: if time_end < time_start: raise ValueError("Ending time smaller than starting time") execution_duration = (time_end - time_start) / 1e9 metrics = PipelineMetrics( pipeline_name=pipeline_name, execution_duration=execution_duration, ) with SESSION.db_engine.begin() as con: con.execute(sql.insert(db.perf_meas).values(**metrics)) return metrics @wrap_result(code_on_error=DEFAULT_DB_ERR_CODE) def _write_performance_metrics_wrapped( pipeline_name: str, time_start: int, time_end: int, ) -> PipelineMetrics: return _write_performance_metrics(pipeline_name, time_start, time_end) def pipeline_sales_forecast( company_id: int | None, start_date: Datetime | None, ) -> JsonExportResponse: PIPELINE_NAME: Final[str] = "sales_forecast" logger.info("[EXT-CALL PIPELINES] Starting main sales forecast pipeline...") t_start = time.perf_counter_ns() result = forecast.pipeline_sales_forecast( SESSION, company_id=company_id, start_date=start_date ) export = JsonExportResponse(result.model_dump_json()) t_end = time.perf_counter_ns() logger.info("[EXT-CALL PIPELINES] Main sales forecast pipeline successful") logger.info("[EXT-CALL PIPELINES] Writing performance metrics...") res = _write_performance_metrics_wrapped( pipeline_name=PIPELINE_NAME, time_start=t_start, time_end=t_end, ) if res.status != STATUS_HANDLER.SUCCESS: logger.error( ( "[DB-WRITE][METRICS] Pipeline: >%s< - Error on writing " "pipeline metrics to database: %s" ), PIPELINE_NAME, res.status, ) else: metrics = res.unwrap() logger.info( "[METRICS] Pipeline: >%s< - Execution time: %.6f", PIPELINE_NAME, metrics["execution_duration"], ) return export def pipeline_sales_forecast_dummy( company_id: int | None, start_date: Datetime | None, ) -> JsonExportResponse: PIPELINE_NAME: Final[str] = "sales_forecast_dummy" logger.info("[EXT-CALL PIPELINES] Starting dummy sales forecast pipeline...") t_start = time.perf_counter_ns() result = forecast.pipeline_sales_dummy( SESSION, company_id=company_id, start_date=start_date, ) export = JsonExportResponse(result.model_dump_json()) t_end = time.perf_counter_ns() logger.info("[EXT-CALL PIPELINES] Dummy sales forecast pipeline successful") logger.info("[EXT-CALL PIPELINES] Writing performance metrics...") res = _write_performance_metrics_wrapped( pipeline_name=PIPELINE_NAME, time_start=t_start, time_end=t_end, ) if res.status != STATUS_HANDLER.SUCCESS: logger.error( ( "[DB-WRITE][METRICS] Pipeline: >%s< - Error on writing " "pipeline metrics to database: %s" ), PIPELINE_NAME, res.status, ) else: metrics = res.unwrap() logger.info( "[METRICS] Pipeline: >%s< - Execution time: %.6f", PIPELINE_NAME, metrics["execution_duration"], ) return export