modular_api_cli/modular_handler/usage_handler.py (102 lines of code) (raw):

import json import os from datetime import datetime, timezone from pathlib import Path from itertools import chain from modular_api.helpers.constants import LOG_FOLDER, ID, TIMESTAMP, KEY from modular_api.helpers.decorators import CommandResponse from modular_api.helpers.exceptions import ModularApiBadRequestException from modular_api.helpers.log_helper import get_logger _LOG = get_logger(__name__) class UsageHandler: def __init__(self, usage_service): self.usage_service = usage_service def get_stats_handler(self, from_month, to_month, display_table, path): _LOG.info(f'Going to get usage statistic. Parameters: from_month ' f'\'{from_month}\', to_month \'{to_month}\', ' f'display_table \'{display_table}\', path \'{path}\'') try: if from_month: fd_dt = datetime.strptime(from_month, '%Y-%m') from_date = int(fd_dt.timestamp()) * 1000 else: utc_time_now = datetime.now(timezone.utc) utc_time_now = utc_time_now.replace( day=1, hour=0, minute=0, second=0) from_date = int(utc_time_now.timestamp() * 1000) if to_month: td_dt = datetime.strptime(to_month, '%Y-%m') td_dt = td_dt.replace(day=1, hour=0, minute=0, second=0) to_date = int(td_dt.timestamp()) * 1000 else: to_date = None except ValueError: _LOG.error('Invalid date format') raise ModularApiBadRequestException( 'Please check date(s) spelling, required format is "yyyy-mm"') if (from_date and to_date) and (from_date >= to_date): _LOG.error('Invalid period') raise ModularApiBadRequestException( 'Start month can not be greater than or equal to the end ' 'month') it = chain.from_iterable( self.usage_service.get_stats(key, from_date, to_date) for key in self.usage_service.modules_info ) raw_result = [i.get_json() for i in it] if not raw_result: _LOG.info('No usage statistic by provided filters') return CommandResponse( message='There is no data by provided filters') table_report = self._prettify_report(raw_result, display_table) if table_report: return CommandResponse(table_title='Statistic', items=table_report) file_path = self._save_report_and_get_path(raw_result, path) _LOG.info(f'Report file has been stored by path: \'{file_path}\'') return CommandResponse( message=f'Report file has been stored by path: \'{file_path}\'') @staticmethod def _prettify_report(data, display_table) -> (list, None): if not display_table: return table_result = list() for item in data: item.pop(ID) item.pop(TIMESTAMP) table_result.append(item) return table_result @staticmethod def _save_report_and_get_path(data, path) -> str: if path: if not os.path.exists(path): _LOG.error(f'Provided path \'{path}\' does not exist') raise ModularApiBadRequestException( f'Seems like path "{path}" does not exist. Please check ' f'spelling') else: pre_configured_user_dir = os.environ.get("M3MODULAR_USER_HOME") if pre_configured_user_dir: path = os.path.join( pre_configured_user_dir, LOG_FOLDER, 'reports') else: path = os.path.join( str(Path.home()), LOG_FOLDER, 'reports') if not os.path.exists(path): os.makedirs(path) tn = datetime.now(timezone.utc) file_name = f'{tn.day}-{tn.month}-{tn.year}-{tn.microsecond}.json' file_path = os.path.join(path, file_name) sorted_list = sorted(data, key=lambda d: d[TIMESTAMP]) modified_list = list() for key, item in enumerate(sorted_list, start=1): item[KEY] = key modified_list.append(item) json_object = json.dumps(sorted_list, indent=4) try: with open(file_path, 'w') as file: file.write(json_object) except PermissionError: raise ModularApiBadRequestException( f'You do not have permissions to write files by path: ' f'\'{path}\'') return file_path