def generate_daily_report(self): item_name = consts.ReportItemName.DAILY_COST.value dataframe = self.collector.get_daily_report() self.data_container.add(item_name, dataframe) item_def: ItemDefinition = self.create_item_definition_from_df( dataframe=dataframe, item_name=item_name, chart_type=ItemType.BAR, group="charts") self.item_defs.append(item_def) account_col_names = dataframe.columns.tolist() account_col_names.remove('dates') self.data_container.add(ReportItemName.DAILY_TOTAL_COST.value, self.get_totals(dataframe)) # generate final cost day date data item final_day = dataframe['dates'].tolist()[-2] self.item_defs.append( ItemDefinition(ReportItemName.LAST_FINAL_DATE.value, ItemType.VALUE, [final_day])) # final day cost for each account for account in account_col_names: cost = dataframe[account].tolist()[-2] self.item_defs.append( ItemDefinition(f'{account}', ItemType.VALUE, [f'${str(cost)}'], group='Account Cost'))
def generate_current_month_forecast(self): item_name = consts.ReportItemName.FORECAST.value dataframe = self.collector.get_current_month_forecast() forecast = dataframe['values'][0] self.data_container.add(item_name, dataframe) self.item_defs.append( ItemDefinition(item_name, ItemType.VALUE, [f'${str(forecast)}']))
def analyze_internal(self): month_totals: DataFrame = self.data_container.get( ReportItemName.MONTHLY_TOTAL_COST.value) last_closed_month = month_totals['values'].values[-2] forecast = self.data_container.get(ReportItemName.FORECAST.value) forecast_per = data_utils.calc_percentage(forecast['values'].values[0], last_closed_month) self.item_defs.append( ItemDefinition(ReportItemName.FORECAST_PER.value, ItemType.VALUE, [forecast_per]))
def analyze_internal(self): daily_totals: DataFrame = self.data_container.get( ReportItemName.DAILY_TOTAL_COST.value) values = daily_totals['values'].values self.item_defs.append( ItemDefinition(ReportItemName.DAILY_TOTAL_COST_MIN.value, ItemType.VALUE, [round(values.min(), 1)])) self.item_defs.append( ItemDefinition(ReportItemName.DAILY_TOTAL_COST_MAX.value, ItemType.VALUE, [round(values.max(), 1)])) self.item_defs.append( ItemDefinition(ReportItemName.DAILY_TOTAL_COST_MEAN.value, ItemType.VALUE, [round(values.mean(), 1)])) self.item_defs.append( ItemDefinition(ReportItemName.DAILY_TOTAL_COST_TOTAL.value, ItemType.VALUE, [round(values.sum(), 1)]))
def generate_services_report(self): item_name = consts.ReportItemName.SERVICES_COST.value dataframe = self.collector.get_services_report() self.data_container.add(item_name, dataframe) item_def: ItemDefinition = self.create_item_definition_from_df( dataframe=dataframe, item_name=item_name, chart_type=ItemType.LINE, group="charts", filtered_keys=self.config.filtered_services) self.item_defs.append(item_def) # calculate services total cost service_names = dataframe.columns.values.tolist() service_names.remove('dates') total_values = {} # sum service cost for service_name in list( filter(lambda i: i not in self.config.filtered_services, service_names)): total_values[service_name] = round( dataframe[service_name].values.sum()) # sort services by cost total_values = { k: v for k, v in sorted( total_values.items(), key=lambda item: item[1], reverse=True) } # top services (5 and others) top = {'others': 0} for i, k in enumerate(total_values): if i <= 5: top[k] = total_values[k] else: top['others'] = top['others'] + total_values[k] item_name = consts.ReportItemName.SERVICES_TOP_COST.value item_def: ItemDefinition = ItemDefinition( item_name, item_type=ItemType.PIE, x=list(top.keys()), y=[DataSeries('values', list(top.values()))], group="charts") self.item_defs.append(item_def)
def create_item_definition(self, cost_results, item_name, chart_type: ItemType, filtered_keys=None, group=None) -> ItemDefinition: if not filtered_keys: filtered_keys = [] x_values = [] data_series = {} for v in cost_results: start = v['TimePeriod']['Start'] end = v['TimePeriod']['End'] x_values.append(f'{start}_{end}') if v['Groups']: for i in v['Groups']: key = i['Keys'][0] if key not in filtered_keys: # map account id to name: if self.config.accounts and key in self.config.accounts: key = self.config.accounts[key] if not data_series.get(key): data_series[key] = DataSeries(key, []) series = data_series[key] series.values.append( float(i['Metrics']['UnblendedCost']['Amount'])) # TODO: support case when no groups are available # else: # update({'Total': float(v['Total']['UnblendedCost']['Amount'])}) return ItemDefinition(item_name, chart_type, x_values, list(data_series.values()), group=group)
def create_item_definition_from_df(self, dataframe: pd.DataFrame, item_name, chart_type: ItemType, group=None, filtered_keys=None) -> ItemDefinition: if not filtered_keys: filtered_keys = [] column_names = dataframe.columns.tolist() column_names = list( filter(lambda i: i == 'dates' or i not in filtered_keys, column_names)) if 'dates' not in column_names: raise Exception("dataframe should have 'dates' column") x_values = dataframe['dates'] column_names.remove('dates') data_series = [] for names in column_names: data_values = dataframe[names].values # sanity check if len(data_values) != len(x_values): raise Exception( 'values array length does not match dates array length') series = DataSeries(names, data_values) data_series.append(series) return ItemDefinition(item_name, chart_type, x_values, data_series, group=group)
def __add_value(name: ReportItemName): val = self.data_container.get_value(name.value) items_defs.append(ItemDefinition(name.value, ItemType.VALUE, [val]))
def _data_to_items_defs(self): items_defs = [] def __add_value(name: ReportItemName): val = self.data_container.get_value(name.value) items_defs.append(ItemDefinition(name.value, ItemType.VALUE, [val])) for item in [ ReportItemName.CURRENT_DATE, ReportItemName.FORECAST_PER, ReportItemName.MONTHLY_TOTAL_COST_MIN, ReportItemName.MONTHLY_TOTAL_COST_MAX, ReportItemName.MONTHLY_TOTAL_COST_MEAN, ReportItemName.MONTHLY_TOTAL_COST_TOTAL, ReportItemName.DAILY_TOTAL_COST_MIN, ReportItemName.DAILY_TOTAL_COST_MAX, ReportItemName.DAILY_TOTAL_COST_MEAN, ReportItemName.DAILY_TOTAL_COST_TOTAL ]: __add_value(item) item_name = ReportItemName.FORECAST.value forecast = self.data_container.get_value(item_name) items_defs.append( ItemDefinition(item_name, ItemType.VALUE, [f'${str(forecast)}'])) item_name = ReportItemName.MONTHLY_COST.value monthly_cost_df = self.data_container.get_value(item_name) items_defs.append( self.create_item_definition_from_df( dataframe=monthly_cost_df, item_name=item_name, chart_type=ItemType.STACK, group=ReportItemGroup.CHARTS.value)) item_name = ReportItemName.DAILY_COST.value daily_cost_df = self.data_container.get_value(item_name) items_defs.append( self.create_item_definition_from_df( dataframe=daily_cost_df, item_name=item_name, chart_type=ItemType.BAR, group=ReportItemGroup.CHARTS.value)) # generate final cost day date data item final_day = daily_cost_df['dates'].tolist()[-2] items_defs.append( ItemDefinition(ReportItemName.LAST_FINAL_DATE.value, ItemType.VALUE, [final_day])) # final day cost for each account account_col_names = daily_cost_df.columns.tolist() account_col_names.remove('dates') for account in account_col_names: cost = daily_cost_df[account].tolist()[-2] items_defs.append( ItemDefinition(f'{account}', ItemType.VALUE, [f'${str(cost)}'], group=ReportItemGroup.ACCOUNT_COST.value)) # services cost item_name = ReportItemName.SERVICES_COST.value services_cost_df = self.data_container.get_value(item_name) item_def: ItemDefinition = self.create_item_definition_from_df( dataframe=services_cost_df, item_name=item_name, chart_type=ItemType.LINE, group=ReportItemGroup.CHARTS.value, filtered_keys=self.filtered_services) items_defs.append(item_def) # calculate services total cost service_names = services_cost_df.columns.values.tolist() service_names.remove('dates') total_values = {} # sum service cost for service_name in list( filter(lambda i: i not in self.filtered_services, service_names)): total_values[service_name] = round( services_cost_df[service_name].values.sum()) # sort services by cost total_values = { k: v for k, v in sorted( total_values.items(), key=lambda item: item[1], reverse=True) } # top services (5 and others) top = {'others': 0} for i, k in enumerate(total_values): if i <= 5: top[k] = total_values[k] else: top['others'] = top['others'] + total_values[k] item_name = ReportItemName.SERVICES_TOP_COST.value item_def: ItemDefinition = ItemDefinition( item_name, item_type=ItemType.PIE, x=list(top.keys()), y=[DataSeries('values', list(top.values()))], group=ReportItemGroup.CHARTS.value) items_defs.append(item_def) # tags cost tag_items = self.data_container.get_by_group(ReportItemGroup.TAGS) for tag_item in tag_items: item_def: ItemDefinition = self.create_item_definition_from_df( dataframe=tag_item.value, item_name=tag_item.name, chart_type=ItemType.LINE, group=ReportItemGroup.TAGS.value) items_defs.append(item_def) return items_defs
def generate_current_date(self): item_name = consts.ReportItemName.CURRENT_DATE.value exec_time_str = format_datetime(self.exec_time, TIME_FORMAT) self.item_defs.append( ItemDefinition(item_name, ItemType.VALUE, [exec_time_str]))