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]