def fill_report_id(report: Report) -> None: report.reportId = report_service.generate_storable_id() report.subjectId = subject_id_map[report.subjectId] \ if report.subjectId in subject_id_map else report.subjectId report.connectId = connected_space_id_map[report.connectId] \ if report.connectId in connected_space_id_map else report.connectId if report.filters is not None: report.filters = ParameterJoint(**replace_ids(report.filters.dict(), replace_topic_and_factor_ids))
def construct_report( report: Optional[Union[dict, Report]]) -> Optional[Report]: if report is None: return None elif isinstance(report, Report): return report else: return Report(**report)
def fake_to_report(self) -> Report: indicators: List[ReportIndicator] = [] report_indicator_column_id = self.indicator.factorId arithmetics = self.inspection.aggregateArithmetics if arithmetics is None or len(arithmetics) == 0: indicators.append(ReportIndicator( columnId=report_indicator_column_id, name='_SUM_', arithmetic=ReportIndicatorArithmetic.SUMMARY)) else: if IndicatorAggregateArithmetic.COUNT in arithmetics or IndicatorAggregateArithmetic.COUNT.value in arithmetics: indicators.append(ReportIndicator( columnId=report_indicator_column_id, name='_COUNT_', arithmetic=ReportIndicatorArithmetic.COUNT)) if IndicatorAggregateArithmetic.SUM in arithmetics or IndicatorAggregateArithmetic.SUM.value in arithmetics: indicators.append(ReportIndicator( columnId=report_indicator_column_id, name='_SUM_', arithmetic=ReportIndicatorArithmetic.SUMMARY)) if IndicatorAggregateArithmetic.AVG in arithmetics or IndicatorAggregateArithmetic.AVG.value in arithmetics: indicators.append(ReportIndicator( columnId=report_indicator_column_id, name='_AVG_', arithmetic=ReportIndicatorArithmetic.AVERAGE)) if IndicatorAggregateArithmetic.MAX in arithmetics or IndicatorAggregateArithmetic.MAX.value in arithmetics: indicators.append(ReportIndicator( columnId=report_indicator_column_id, name='_MAX_', arithmetic=ReportIndicatorArithmetic.MAXIMUM)) if IndicatorAggregateArithmetic.MIN in arithmetics or IndicatorAggregateArithmetic.MIN.value in arithmetics: indicators.append(ReportIndicator( columnId=report_indicator_column_id, name='_MIN_', arithmetic=ReportIndicatorArithmetic.MINIMUM)) dimensions: List[ReportDimension] = [] bucket_on_column = self.find_column_of_measure_on_dimension() if bucket_on_column is not None: dimensions.append(ReportDimension(columnId=bucket_on_column.columnId, name='_BUCKET_ON_')) time_group_column = self.find_column_of_measure_on_time_dimension() if time_group_column is not None: fake_column = ArrayHelper(self.subject.dataset.columns) \ .find(lambda x: x.columnId == self.FAKE_TIME_GROUP_COLUMN_ID) if fake_column is None: dimensions.append(ReportDimension(columnId=time_group_column.columnId, name='_TIME_GROUP_')) else: dimensions.append(ReportDimension(columnId=self.FAKE_TIME_GROUP_COLUMN_ID, name='_TIME_GROUP_')) if len(dimensions) == 0: raise IndicatorKernelException('Neither time group nor bucket not found.') report_filter = self.fake_time_range_to_report() if report_filter is None: return Report(indicators=indicators, dimensions=dimensions) else: return Report(indicators=indicators, dimensions=dimensions, filters=report_filter)
def fake_to_report(self, subject: Subject) -> Report: # in subject, # 1st column is value, # 2nd column is time group when there is 3rd column, or is measure on when there is no 3rd column, # 3rd column is measure on indicators: List[ReportIndicator] = [] arithmetics = self.inspection.aggregateArithmetics if arithmetics is None or len(arithmetics) == 0: indicators.append(ReportIndicator(columnId='1', name='_SUM_', arithmetic=ReportIndicatorArithmetic.SUMMARY)) else: if IndicatorAggregateArithmetic.COUNT in arithmetics or IndicatorAggregateArithmetic.COUNT.value in arithmetics: indicators.append( ReportIndicator(columnId='1', name='_COUNT_', arithmetic=ReportIndicatorArithmetic.COUNT)) if IndicatorAggregateArithmetic.SUM in arithmetics or IndicatorAggregateArithmetic.SUM.value in arithmetics: indicators.append( ReportIndicator(columnId='1', name='_SUM_', arithmetic=ReportIndicatorArithmetic.SUMMARY)) if IndicatorAggregateArithmetic.AVG in arithmetics or IndicatorAggregateArithmetic.AVG.value in arithmetics: indicators.append( ReportIndicator(columnId='1', name='_AVG_', arithmetic=ReportIndicatorArithmetic.AVERAGE)) if IndicatorAggregateArithmetic.MAX in arithmetics or IndicatorAggregateArithmetic.MAX.value in arithmetics: indicators.append( ReportIndicator(columnId='1', name='_MAX_', arithmetic=ReportIndicatorArithmetic.MAXIMUM)) if IndicatorAggregateArithmetic.MIN in arithmetics or IndicatorAggregateArithmetic.MIN.value in arithmetics: indicators.append( ReportIndicator(columnId='1', name='_MIN_', arithmetic=ReportIndicatorArithmetic.MINIMUM)) dimensions: List[ReportDimension] = [] if len(subject.dataset.columns) == 3: dimensions.append(ReportDimension(columnId='3', name='_BUCKET_ON_')) fake_column = ArrayHelper(subject.dataset.columns) \ .find(lambda x: x.columnId == self.FAKE_TIME_GROUP_COLUMN_ID) if fake_column is None: dimensions.append(ReportDimension(columnId='2', name='_TIME_GROUP_')) else: dimensions.append(ReportDimension(columnId=self.FAKE_TIME_GROUP_COLUMN_ID, name='_TIME_GROUP_')) elif len(subject.dataset.columns) == 2: time_group_existing, _, _ = self.has_time_group() if time_group_existing: fake_column = ArrayHelper(subject.dataset.columns) \ .find(lambda x: x.columnId == self.FAKE_TIME_GROUP_COLUMN_ID) if fake_column is None: dimensions.append(ReportDimension(columnId='2', name='_TIME_GROUP_')) else: dimensions.append(ReportDimension(columnId=self.FAKE_TIME_GROUP_COLUMN_ID, name='_TIME_GROUP_')) else: dimensions.append(ReportDimension(columnId='2', name='_BUCKET_ON_')) else: raise IndicatorKernelException('Neither time group nor bucket on found.') return Report(indicators=indicators, dimensions=dimensions)
def copy_and_create_report(report: Report, subject_id: SubjectId) -> Report: report_service.redress_storable_id(report) report.subjectId = subject_id report.connectId = connected_space.connectId report.userId = connected_space.userId report.tenantId = connected_space.tenantId report.lastVisitTime = now # remove thumbnail report.simulateThumbnail = None # noinspection PyTypeChecker return report_service.create(report)
def deserialize(self, row: EntityRow) -> Report: report = Report(reportId=row.get('report_id'), name=row.get('name'), subjectId=row.get('subject_id'), connectId=row.get('connect_id'), filters=row.get('filters'), funnels=row.get('funnels'), indicators=row.get('indicators'), dimensions=row.get('dimensions'), description=row.get('description'), rect=row.get('rect'), chart=row.get('chart'), simulating=row.get('simulating'), simulateData=row.get('simulate_data'), simulateThumbnail=row.get('simulate_thumbnail')) # noinspection PyTypeChecker report: Report = AuditableShaper.deserialize(row, report) # noinspection PyTypeChecker report: Report = UserBasedTupleShaper.deserialize(row, report) # noinspection PyTypeChecker report: Report = LastVisitShaper.deserialize(row, report) return report
def action(factor_id: FactorId) -> Report: arithmetic = self.achievementIndicator.aggregateArithmetic if arithmetic is None: report_indicator = ReportIndicator( columnId=factor_id, name='_SUM_', arithmetic=ReportIndicatorArithmetic.SUMMARY) elif IndicatorAggregateArithmetic.COUNT == arithmetic or IndicatorAggregateArithmetic.COUNT.value == arithmetic: report_indicator = ReportIndicator( columnId=factor_id, name='_COUNT_', arithmetic=ReportIndicatorArithmetic.COUNT) elif IndicatorAggregateArithmetic.SUM == arithmetic or IndicatorAggregateArithmetic.SUM.value == arithmetic: report_indicator = ReportIndicator( columnId=factor_id, name='_SUM_', arithmetic=ReportIndicatorArithmetic.SUMMARY) elif IndicatorAggregateArithmetic.AVG == arithmetic or IndicatorAggregateArithmetic.AVG.value == arithmetic: report_indicator = ReportIndicator( columnId=factor_id, name='_AVG_', arithmetic=ReportIndicatorArithmetic.AVERAGE) elif IndicatorAggregateArithmetic.MAX == arithmetic or IndicatorAggregateArithmetic.MAX.value == arithmetic: report_indicator = ReportIndicator( columnId=factor_id, name='_MAX_', arithmetic=ReportIndicatorArithmetic.MAXIMUM) elif IndicatorAggregateArithmetic.MIN == arithmetic or IndicatorAggregateArithmetic.MIN.value == arithmetic: report_indicator = ReportIndicator( columnId=factor_id, name='_MIN_', arithmetic=ReportIndicatorArithmetic.MINIMUM) else: raise IndicatorKernelException( f'Indicator aggregate arithmetics[{arithmetic}] is not supported.' ) return Report(indicators=[report_indicator], dimensions=[])
def action(report: Report) -> Report: report.userId = principal_service.get_user_id() report.tenantId = principal_service.get_tenant_id() report.lastVisitTime = get_current_time_in_seconds() if report.simulating is None: report.simulating = False if report_service.is_storable_id_faked(report.reportId): subject_id = report.subjectId if is_blank(subject_id): raise_400('Subject id is required.') subject_service = get_subject_service(report_service) existing_subject: Optional[Subject] = subject_service.find_by_id(subject_id) if existing_subject is None: raise_400('Incorrect subject id.') elif existing_subject.tenantId != report.tenantId or existing_subject.userId != report.userId: raise_403() else: report.connectId = existing_subject.connectId report_service.redress_storable_id(report) # noinspection PyTypeChecker report: Report = report_service.create(report) else: # noinspection PyTypeChecker existing_report: Optional[Report] = report_service.find_by_id(report.reportId) if existing_report is not None: if existing_report.tenantId != report.tenantId: raise_403() if existing_report.userId != report.userId: raise_403() report.subjectId = existing_report.subjectId report.connectId = existing_report.connectId # noinspection PyTypeChecker report: Report = report_service.update(report) return report
async def query_dataset( criteria: SubjectDatasetCriteria, principal_service: PrincipalService = Depends(get_console_principal) ) -> DataPage: subject_id = criteria.subjectId subject_name = criteria.subjectName indicators = criteria.indicators conditions = criteria.conditions if is_blank(subject_id) and is_blank(subject_name): raise_400( 'At least one of subject id or subject name needs to be provided.') if indicators is None or len(indicators) == 0: raise_400('At least one indicator needs to be declared.') if is_not_blank(subject_id): subject: Optional[Subject] = get_subject_service( principal_service).find_by_id(subject_id) else: subject: Optional[Subject] = get_subject_service( principal_service).find_by_name(subject_name) if subject is None: raise_400( f'Subject not found by given criteria[id={subject_id}, name={subject_name}].' ) subject_column_map: Dict[str, SubjectDatasetColumn] = ArrayHelper(subject.dataset.columns) \ .to_map(lambda x: x.alias, lambda x: x) def to_report_indicator( indicator: SubjectDatasetCriteriaIndicator) -> ReportIndicator: name = indicator.name dataset_column = subject_column_map.get(name) if dataset_column is None: raise_400(f'Cannot find column[name={name}] from subject.') arithmetic = ReportIndicatorArithmetic.NONE if indicator.arithmetic == SubjectDatasetCriteriaIndicatorArithmetic.COUNT: arithmetic = ReportIndicatorArithmetic.COUNT elif indicator.arithmetic == SubjectDatasetCriteriaIndicatorArithmetic.SUMMARY: arithmetic = ReportIndicatorArithmetic.SUMMARY elif indicator.arithmetic == SubjectDatasetCriteriaIndicatorArithmetic.AVERAGE: arithmetic = ReportIndicatorArithmetic.AVERAGE elif indicator.arithmetic == SubjectDatasetCriteriaIndicatorArithmetic.MAXIMUM: arithmetic = ReportIndicatorArithmetic.MAXIMUM elif indicator.arithmetic == SubjectDatasetCriteriaIndicatorArithmetic.MINIMUM: arithmetic = ReportIndicatorArithmetic.MINIMUM elif indicator.arithmetic == SubjectDatasetCriteriaIndicatorArithmetic.NONE or indicator.arithmetic is None: arithmetic = ReportIndicatorArithmetic.NONE else: raise_400( f'Indicator arithmetic[{indicator.arithmetic}] is not supported.' ) return ReportIndicator(columnId=dataset_column.columnId, arithmetic=arithmetic, name=indicator.alias) def to_report_joint(joint: ParameterJoint) -> ParameterJoint: return ParameterJoint( jointType=ParameterJointType.AND if joint.jointType is None else joint.jointType, filters=ArrayHelper(joint.filters).map(to_report_filter).to_list()) def translate_topic_factor( param: TopicFactorParameter) -> TopicFactorParameter: factor_id = param.factorId # alias name on subject dataset_column = subject_column_map.get(factor_id) if dataset_column is None: raise_400(f'Cannot find column[name={factor_id}] from subject.') # topicId is not need here since subject will be build as a sub query return TopicFactorParameter(kind=ParameterKind.TOPIC, factorId=dataset_column.columnId) def translate_constant(param: ConstantParameter) -> ConstantParameter: # in constant, use alias name from subject columns # translate is not needed here return ConstantParameter(kind=ParameterKind.CONSTANT, value=param.value) def translate_computed(param: ComputedParameter) -> ComputedParameter: return ComputedParameter( kind=ParameterKind.COMPUTED, conditional=param.conditional, on=to_report_joint(param.on) if param.on is not None else None, type=param.type, parameters=ArrayHelper( param.parameters).map(translate_parameter).to_list()) def translate_parameter(parameter: Parameter) -> Parameter: if isinstance(parameter, TopicFactorParameter): return translate_topic_factor(parameter) elif isinstance(parameter, ConstantParameter): return translate_constant(parameter) elif isinstance(parameter, ComputedParameter): return translate_computed(parameter) else: raise_400( f'Cannot determine given expression[{parameter.dict()}].') def to_report_expression( expression: ParameterExpression) -> ParameterExpression: return ParameterExpression(left=translate_parameter(expression.left), operator=expression.operator, right=None if expression.right is None else translate_parameter(expression.right)) def to_report_filter(condition: ParameterCondition) -> ParameterCondition: if isinstance(condition, ParameterExpression): return to_report_expression(condition) elif isinstance(condition, ParameterJoint): return to_report_joint(condition) else: raise_400(f'Cannot determine given condition[{condition.dict()}].') if conditions is None or len(conditions) == 0: filters = None else: filters = ParameterJoint( jointType=ParameterJointType.AND, filters=ArrayHelper(conditions).map(to_report_filter).to_list()) # fake a report to query data report = Report( indicators=ArrayHelper(indicators).map(to_report_indicator).to_list(), filters=filters) page_size = ask_dataset_page_max_rows() if criteria.pageSize is None or criteria.pageSize < 1 or criteria.pageSize > page_size: page_size = ask_dataset_page_max_rows() else: page_size = criteria.pageSize pageable = Pageable(pageNumber=1 if criteria.pageNumber is None or criteria.pageNumber < 1 else criteria.pageNumber, pageSize=page_size) return get_report_data_service(subject, report, principal_service).page(pageable)
def build_hierarchy_from_report(report: Report, subject_id: SubjectId, connect_id: ConnectedSpaceId) -> None: report.connectId = connect_id report.subjectId = subject_id
def set_subject_id(report: Report, subject_id: SubjectId) -> None: report.subjectId = subject_id
def set_user_id_to_report(report: Report, user_id: UserId) -> None: report.userId = user_id
def test_single_topic(self): self.prepare_data() subject = Subject(dataset=SubjectDataset(columns=[ SubjectDatasetColumn( columnId='1', parameter=ComputedParameter( kind=ParameterKind.COMPUTED, type=ParameterComputeType.ADD, parameters=[ TopicFactorParameter(kind=ParameterKind.TOPIC, topicId='1', factorId='1'), ConstantParameter(kind=ParameterKind.CONSTANT, value='2') ]), alias='Column1', arithmetic=SubjectColumnArithmetic.SUMMARY), SubjectDatasetColumn( columnId='2', parameter=TopicFactorParameter( kind=ParameterKind.TOPIC, topicId='1', factorId='1'), alias='Column2'), SubjectDatasetColumn(columnId='3', parameter=ConstantParameter( kind=ParameterKind.CONSTANT, value='{&now}'), alias='Column3'), SubjectDatasetColumn(columnId='4', parameter=ConstantParameter( kind=ParameterKind.CONSTANT, value='HELLO WORLD!'), alias='Column4'), SubjectDatasetColumn( columnId='5', parameter=ComputedParameter( kind=ParameterKind.COMPUTED, type=ParameterComputeType.ADD, parameters=[ ConstantParameter(kind=ParameterKind.CONSTANT, value='201'), ConstantParameter(kind=ParameterKind.CONSTANT, value='102') ]), alias='Column5'), SubjectDatasetColumn(columnId='6', parameter=ComputedParameter( kind=ParameterKind.COMPUTED, type=ParameterComputeType.YEAR_OF, parameters=[ ConstantParameter( kind=ParameterKind.CONSTANT, value='2022/03/03'), ]), alias='Column6'), SubjectDatasetColumn( columnId='7', parameter=TopicFactorParameter( kind=ParameterKind.TOPIC, topicId='1', factorId='2'), alias='Column7') ]), connectId='1', userId='1', tenantId='1') subject_data_service = SubjectDataService( subject, create_fake_principal_service()) page = subject_data_service.page(Pageable(pageNumber=1, pageSize=100)) print(page) report = Report( indicators=[ ReportIndicator(columnId='1', name='sum_value', arithmetic=ReportIndicatorArithmetic.SUMMARY) ], dimensions=[ReportDimension(columnId='7', name='enabled')], filters=ParameterJoint( jointType=ParameterJointType.AND, filters=[ ParameterExpression( left=TopicFactorParameter(kind=ParameterKind.TOPIC, factorId='7'), operator=ParameterExpressionOperator.EQUALS, right=ConstantParameter(kind=ParameterKind.CONSTANT, value='true')) ])) report_data_service = ReportDataService( subject, report, create_fake_principal_service(), False) data = report_data_service.find() print(data)
def set_storable_id(self, storable: Report, storable_id: ReportId) -> Report: storable.reportId = storable_id return storable