def __init__(self, parameters, user_id=0, recurrent_parent_id=None, created=None): """ Parameters: parameters : dictionary containing the following required keys: name : the name of the report cohort : dictionary defining the cohort, has keys: id : the id of the cohort metric : dictionary defining the metric, has keys: name : the name of the python class to instantiate recurrent : whether to rerun this daily public : whether to expose results publicly user_id : the user wishing to run this report recurrent_parent_id : the parent PersistentReport.id for a recurrent run created : if set, represents the date of a recurrent run Raises: KeyError if required parameters are missing """ # get cohort cohort_dict = parameters['cohort'] session = db.get_session() try: cohort = Cohort.get_safely(session, user_id, by_id=cohort_dict['id']) finally: session.close() parameters['cohort']['size'] = len(cohort) # construct metric metric_dict = parameters['metric'] metric = metric_classes[metric_dict['name']](**metric_dict) # if this is a recurrent run, don't show it in the UI if recurrent_parent_id is not None: self.show_in_ui = False super(RunReport, self).__init__( name=parameters['name'], user_id=user_id, parameters=parameters, public=parameters.get('public', False), recurrent=parameters.get('recurrent', False), recurrent_parent_id=recurrent_parent_id, created=created, ) validate_report = ValidateReport( metric, cohort, recurrent_parent_id is None, user_id=user_id ) if validate_report.valid(): self.children = [AggregateReport( metric, cohort, metric_dict, parameters=parameters, user_id=user_id )] else: self.children = [validate_report]
def parse_request(self, desired_responses): children = [] metric_names = [] cohort_names = [] for cohort_metric_dict in desired_responses: # get cohort cohort_dict = cohort_metric_dict['cohort'] session = db.get_session() try: cohort = Cohort.get_safely(session, self.user_id, by_id=cohort_dict['id']) finally: session.close() # construct metric metric_dict = cohort_metric_dict['metric'] class_name = metric_dict['name'] metric_class = metric_classes[class_name] metric = metric_class(**metric_dict) metric_names.append(metric.label) cohort_names.append(cohort.name) validate_report = ValidateReport(metric, cohort) if validate_report.valid(): # construct and start RunReport output_child = AggregateReport( cohort, metric, individual=metric_dict['individualResults'], aggregate=metric_dict['aggregateResults'], aggregate_sum=metric_dict['aggregateSum'], aggregate_average=metric_dict['aggregateAverage'], aggregate_std_deviation=metric_dict['aggregateStandardDeviation'], name=cohort_metric_dict['name'], user_id=self.user_id, ) children.append(output_child) else: children.append(validate_report) metric_names = deduplicate(metric_names) cohort_names = deduplicate(cohort_names) self.name = ', '.join(metric_names) + ' for ' + ', '.join(cohort_names) self.children = children
def __init__(self, parameters, user_id=0, recurrent_parent_id=None, created=None, persistent_id=None): """ Parameters: parameters : dictionary containing the following required keys: name : the name of the report cohort : dictionary defining the cohort, has keys: id : the id of the cohort metric : dictionary defining the metric, has keys: name : the name of the python class to instantiate recurrent : whether to rerun this daily public : whether to expose results publicly user_id : the user wishing to run this report recurrent_parent_id : the parent ReportStore.id for a recurrent run created : if set, represents the date of a recurrent run. This need not be the timestamp when the recurrent run has been created -- for example when backfilling. Hence, this does not fully match the semantics of the word 'created'. But since neither start nor end date have a separate column in the report table in the database, the covered period for backfilled recurring reports would be hard to identify when only looking at the raw database tables. To overcome this issue, we abuse the created date here. Raises: KeyError if required parameters are missing """ # get cohort cohort_service = CohortService() cohort_dict = parameters['cohort'] session = db.get_session() cohort = cohort_service.get(session, user_id, by_id=cohort_dict['id']) parameters['cohort']['size'] = cohort.size # construct metric metric_dict = parameters['metric'] metric = metric_classes[metric_dict['name']](**metric_dict) # if this is a recurrent run, don't show it in the UI if recurrent_parent_id is not None: self.show_in_ui = False public = parameters.get('public', False) recurrent = parameters.get('recurrent', False) super(RunReport, self).__init__( name=parameters['name'], user_id=user_id, parameters=parameters, public=public, recurrent=recurrent, recurrent_parent_id=recurrent_parent_id, created=created, store=True, persistent_id=persistent_id ) self.recurrent_parent_id = recurrent_parent_id self.public = public validate_report = ValidateReport( metric, cohort, recurrent_parent_id is None, user_id=user_id ) if validate_report.valid(): if recurrent and recurrent_parent_id is None: # Valid parent recurrent report # We do not add children that compute data as parent recurrent # reports just help the scheduler orchestrate child runs. # However, we employ a NullReport to allow coalescing even # when there was no recurrent run yet. self.children = [NullReport()] else: # Valid, but not a parent recurring report, so we add the child # node that does the real computation self.children = [AggregateReport( metric, cohort, metric_dict, parameters=parameters, user_id=user_id )] else: self.children = [validate_report]