Beispiel #1
0
    def validate_params(self, params):

        start_date_str = params['start_date']
        end_date_str = params['end_date']
        enrollment_statuses = params['enrollment_statuses']
        awardees = params['awardees']
        stratification = params['stratification']

        # Validate dates
        if not start_date_str or not end_date_str:
            raise BadRequest('Start date and end date should not be empty')
        try:
            start_date = datetime.datetime.strptime(start_date_str,
                                                    DATE_FORMAT).date()
        except ValueError:
            raise BadRequest('Invalid start date: %s' % start_date_str)
        try:
            end_date = datetime.datetime.strptime(end_date_str,
                                                  DATE_FORMAT).date()
        except ValueError:
            raise BadRequest('Invalid end date: %s' % end_date_str)
        date_diff = abs((end_date - start_date).days)
        if date_diff > DAYS_LIMIT:
            raise BadRequest('Difference between start date and end date ' \
                             'should not be greater than %s days' % DAYS_LIMIT)
        params['start_date'] = start_date
        params['end_date'] = end_date

        # Validate awardees, get ID list
        awardee_ids = []
        for awardee in awardees:
            awardee_id = get_awardee_id_from_name({'awardee': awardee},
                                                  self.hpo_dao)
            if awardee_id == None:
                raise BadRequest('Invalid awardee name: %s' % awardee)
            awardee_ids.append(awardee_ids)
        params['awardee_ids'] = awardee_ids

        # Validate enrollment statuses
        try:
            params["enrollment_statuses"] = [
                EnrollmentStatus(val) for val in enrollment_statuses
            ]
        except TypeError:
            valid_enrollment_statuses = EnrollmentStatus.to_dict()
            for enrollment_status in enrollment_statuses:
                if enrollment_status not in valid_enrollment_statuses:
                    raise BadRequest('Invalid enrollment status: %s' %
                                     enrollment_status)

        # Validate stratifications
        try:
            params['stratification'] = Stratifications(
                params['stratification'])
        except TypeError:
            raise BadRequest('Invalid stratification: %s' % stratification)

        return params
    def get_filtered_results(self, stratification, start_date, end_date,
                             history, awardee_ids, enrollment_statuses,
                             sample_time_def):
        """Queries DB, returns results in format consumed by front-end

    :param start_date: Start date object
    :param end_date: End date object
    :param awardee_ids: indicate awardee ids
    :param enrollment_statuses: indicate the enrollment status
    :param sample_time_def: indicate how to filter the core participant
    :param history: query for history data from metrics cache table
    :param stratification: How to stratify (layer) results, as in a stacked bar chart
    :return: Filtered, stratified results by date
    """

        # Filters for participant_summary (ps) and participant (p) table
        # filters_sql_ps is used in the general case when we're querying participant_summary
        # filters_sql_p is used when also LEFT OUTER JOINing p and ps
        facets = {
            'enrollment_statuses':
            [EnrollmentStatus(val) for val in enrollment_statuses],
            'awardee_ids':
            awardee_ids
        }
        filters_sql_ps = self.get_facets_sql(facets, stratification)
        filters_sql_p = self.get_facets_sql(facets,
                                            stratification,
                                            table_prefix='p')

        if str(history) == 'TRUE' and stratification == Stratifications.TOTAL:
            dao = MetricsEnrollmentStatusCacheDao()
            return dao.get_total_interested_count(start_date, end_date,
                                                  awardee_ids)
        elif str(
                history
        ) == 'TRUE' and stratification == Stratifications.ENROLLMENT_STATUS:
            dao = MetricsEnrollmentStatusCacheDao()
            return dao.get_latest_version_from_cache(start_date, end_date,
                                                     awardee_ids)
        elif str(
                history
        ) == 'TRUE' and stratification == Stratifications.GENDER_IDENTITY:
            dao = MetricsGenderCacheDao()
            return dao.get_latest_version_from_cache(start_date, end_date,
                                                     awardee_ids,
                                                     enrollment_statuses)
        elif str(history
                 ) == 'TRUE' and stratification == Stratifications.AGE_RANGE:
            dao = MetricsAgeCacheDao()
            return dao.get_latest_version_from_cache(start_date, end_date,
                                                     awardee_ids,
                                                     enrollment_statuses)
        elif str(history) == 'TRUE' and stratification == Stratifications.RACE:
            dao = MetricsRaceCacheDao()
            return dao.get_latest_version_from_cache(start_date, end_date,
                                                     awardee_ids,
                                                     enrollment_statuses)
        elif str(history) == 'TRUE' and stratification in [
                Stratifications.FULL_STATE, Stratifications.FULL_CENSUS,
                Stratifications.FULL_AWARDEE, Stratifications.GEO_STATE,
                Stratifications.GEO_CENSUS, Stratifications.GEO_AWARDEE
        ]:
            dao = MetricsRegionCacheDao()
            return dao.get_latest_version_from_cache(end_date, stratification,
                                                     awardee_ids,
                                                     enrollment_statuses)
        elif str(history
                 ) == 'TRUE' and stratification == Stratifications.LANGUAGE:
            dao = MetricsLanguageCacheDao()
            return dao.get_latest_version_from_cache(start_date, end_date,
                                                     awardee_ids,
                                                     enrollment_statuses)
        elif str(history
                 ) == 'TRUE' and stratification == Stratifications.LIFECYCLE:
            dao = MetricsLifecycleCacheDao()
            return dao.get_latest_version_from_cache(end_date, awardee_ids)
        elif stratification == Stratifications.TOTAL:
            strata = ['TOTAL']
            sql = self.get_total_sql(filters_sql_ps)
        elif stratification == Stratifications.ENROLLMENT_STATUS:
            strata = [str(val) for val in EnrollmentStatus]
            sql = self.get_enrollment_status_sql(filters_sql_p,
                                                 sample_time_def)
        elif stratification == Stratifications.EHR_CONSENT:
            strata = ['EHR_CONSENT']
            sql = self.get_total_sql(filters_sql_ps, ehr_count=True)
        elif stratification == Stratifications.EHR_RATIO:
            strata = ['EHR_RATIO']
            sql = self.get_ratio_sql(filters_sql_ps)
        else:
            raise BadRequest('Invalid stratification: %s' % stratification)

        params = {'start_date': start_date, 'end_date': end_date}

        results_by_date = []

        with self.session() as session:
            cursor = session.execute(sql, params)

        # Iterate through each result (by date), transforming tabular SQL results
        # into expected list-of-dictionaries response format
        try:
            results = cursor.fetchall()
            for result in results:
                date = result[-1]
                metrics = {}
                values = result[:-1]
                for i, value in enumerate(values):
                    key = strata[i]
                    if value is None or (stratification
                                         == Stratifications.ENROLLMENT_STATUS
                                         and enrollment_statuses
                                         and key not in enrollment_statuses):
                        value = 0
                    metrics[key] = float(
                        value
                    ) if stratification == Stratifications.EHR_RATIO else int(
                        value)
                results_by_date.append({'date': str(date), 'metrics': metrics})
        finally:
            cursor.close()

        return results_by_date
# Note that we depend on the participant_summary table containing only consented
# participants, by definition. Therefore these metrics only cover consented
# individuals.
_SQL_AGGREGATIONS = [
  _SqlAggregation(
      MetricsKey.ENROLLMENT_STATUS,
      """
      SELECT enrollment_status, COUNT(*)
      FROM participant_summary
      WHERE {summary_filter_sql}
      GROUP BY 1;
      """.format(summary_filter_sql=_SUMMARY_FILTER_SQL),
      # Rewrite INTERESTED to CONSENTED, see note above.
      lambda v: ('CONSENTED' if v is EnrollmentStatus.INTERESTED.number
                 else EnrollmentStatus.lookup_by_number(v).name),
      None),
  # TODO(calbach): Verify whether we need to be conditionally trimming these
  # prefixes or leaving them unmodified. Unclear if all codes will have prefix
  # "PMI_".
  _SqlAggregation(
      MetricsKey.GENDER,
      """
      SELECT
        CASE
         WHEN code.value IS NULL THEN 'UNSET'
         ELSE code.value
        END, ps.count
      FROM (
       SELECT gender_identity_id, COUNT(*) count
       FROM participant_summary
Beispiel #4
0
    def validate_params(self, start_date_str, end_date_str, stratification_str,
                        enrollment_statuses, awardees, history):
        """Validates URL parameters, and converts human-friendly values to canonical form

    :param start_date_str: Start date string, e.g. '2018-01-01'
    :param end_date_str: End date string, e.g. '2018-01-31'
    :param stratification_str: How to stratify (layer) results, as in a stacked bar chart
    :param enrollment_statuses: enrollment level filters
    :param awardees: awardee name filters
    :param history: indicate if it's for historical data
    :return: Validated parameters in canonical form
    """

        params = {}

        # Validate stratifications
        try:
            params['stratification'] = Stratifications(stratification_str)
        except TypeError:
            raise BadRequest('Invalid stratification: %s' % stratification_str)

        if params['stratification'] in [
                Stratifications.FULL_STATE, Stratifications.FULL_CENSUS,
                Stratifications.FULL_AWARDEE, Stratifications.LIFECYCLE
        ]:
            # Validate dates
            if not end_date_str:
                raise BadRequest('end date should not be empty')
            start_date = datetime.datetime.strptime('2017-01-01',
                                                    DATE_FORMAT).date()
            try:
                end_date = datetime.datetime.strptime(end_date_str,
                                                      DATE_FORMAT).date()
            except ValueError:
                raise BadRequest('Invalid end date: %s' % end_date_str)

            params['start_date'] = start_date
            params['end_date'] = end_date
        else:
            # Validate dates
            if not start_date_str or not end_date_str:
                raise BadRequest('Start date and end date should not be empty')
            try:
                start_date = datetime.datetime.strptime(
                    start_date_str, DATE_FORMAT).date()
            except ValueError:
                raise BadRequest('Invalid start date: %s' % start_date_str)
            try:
                end_date = datetime.datetime.strptime(end_date_str,
                                                      DATE_FORMAT).date()
            except ValueError:
                raise BadRequest('Invalid end date: %s' % end_date_str)
            date_diff = abs((end_date - start_date).days)
            if history != 'TRUE' and date_diff > DAYS_LIMIT_FOR_REALTIME_DATA:
                raise BadRequest('Difference between start date and end date '
                                 'should not be greater than %s days' %
                                 DAYS_LIMIT_FOR_REALTIME_DATA)
            if history == 'TRUE' and date_diff > DAYS_LIMIT_FOR_HISTORY_DATA:
                raise BadRequest('Difference between start date and end date '
                                 'should not be greater than %s days' %
                                 DAYS_LIMIT_FOR_HISTORY_DATA)

            params['start_date'] = start_date
            params['end_date'] = end_date

        # Validate awardees, get ID list
        awardee_ids = []
        if awardees is not None:
            awardees = awardees.split(',')
            for awardee in awardees:
                if awardee != '':
                    awardee_id = get_awardee_id_from_name({'awardee': awardee},
                                                          self.hpo_dao)
                    if awardee_id == None:
                        raise BadRequest('Invalid awardee name: %s' % awardee)
                    awardee_ids.append(awardee_id)
        params['awardee_ids'] = awardee_ids

        # Validate enrollment statuses
        if enrollment_statuses is not None:
            enrollment_statuses = enrollment_statuses.split(',')
            try:
                params['enrollment_statuses'] = [
                    EnrollmentStatus(val) for val in enrollment_statuses
                ]
            except TypeError:
                valid_enrollment_statuses = EnrollmentStatus.to_dict()
                for enrollment_status in enrollment_statuses:
                    if enrollment_status != '':
                        if enrollment_status not in valid_enrollment_statuses:
                            raise BadRequest('Invalid enrollment status: %s' %
                                             enrollment_status)

        return params
  def validate_params(self, params):

    filters = {}

    # Validate stratifications
    try:
      filters['stratification'] = Stratifications(params['stratification'])
    except TypeError:
      raise BadRequest('Invalid stratification: %s' % params['stratification'])

    if filters['stratification'] in [Stratifications.FULL_STATE, Stratifications.FULL_CENSUS,
                                     Stratifications.FULL_AWARDEE, Stratifications.GEO_STATE,
                                     Stratifications.GEO_CENSUS, Stratifications.GEO_AWARDEE,
                                     Stratifications.LIFECYCLE]:
      # Validate dates
      if not params['end_date']:
        raise BadRequest('end date should not be empty')
      try:
        end_date = datetime.datetime.strptime(params['end_date'], DATE_FORMAT).date()
        start_date = end_date
      except ValueError:
        raise BadRequest('Invalid end date: %s' % params['end_date'])

      filters['start_date'] = start_date
      filters['end_date'] = end_date
    else:
      # Validate dates
      if not params['start_date'] or not params['end_date']:
        raise BadRequest('Start date and end date should not be empty')
      try:
        start_date = datetime.datetime.strptime(params['start_date'], DATE_FORMAT).date()
      except ValueError:
        raise BadRequest('Invalid start date: %s' % params['start_date'])
      try:
        end_date = datetime.datetime.strptime(params['end_date'], DATE_FORMAT).date()
      except ValueError:
        raise BadRequest('Invalid end date: %s' % params['end_date'])
      date_diff = abs((end_date - start_date).days)
      if params['history'] != 'TRUE' and date_diff > DAYS_LIMIT_FOR_REALTIME_DATA:
        raise BadRequest('Difference between start date and end date '
                         'should not be greater than %s days' % DAYS_LIMIT_FOR_REALTIME_DATA)
      if params['history'] == 'TRUE' and date_diff > DAYS_LIMIT_FOR_HISTORY_DATA:
        raise BadRequest('Difference between start date and end date '
                         'should not be greater than %s days' % DAYS_LIMIT_FOR_HISTORY_DATA)

      filters['start_date'] = start_date
      filters['end_date'] = end_date

    # Validate awardees, get ID list
    awardee_ids = []
    if params['awardees'] is not None:
      awardees = params['awardees'].split(',')
      for awardee in awardees:
        if awardee != '':
          awardee_id = get_awardee_id_from_name({'awardee': awardee}, self.hpo_dao)
          if awardee_id is None:
            raise BadRequest('Invalid awardee name: %s' % awardee)
          awardee_ids.append(awardee_id)
    filters['awardee_ids'] = awardee_ids

    # Validate enrollment statuses
    enrollment_status_strs = []
    if params['enrollment_statuses'] is not None:
      enrollment_statuses = params['enrollment_statuses'].split(',')
      try:
        enrollment_status_strs = [str(EnrollmentStatus(val)) for val in enrollment_statuses]
      except TypeError:
        valid_enrollment_statuses = EnrollmentStatus.to_dict()
        for enrollment_status in enrollment_statuses:
          if enrollment_status != '':
            if enrollment_status not in valid_enrollment_statuses:
              raise BadRequest('Invalid enrollment status: %s' % enrollment_status)
    filters['enrollment_statuses'] = enrollment_status_strs

    if params['sample_time_def'] and params['sample_time_def'] not in ['STORED', 'ORDERED']:
      raise BadRequest('Invalid value for parameter filterBy: %s' % params['sample_time_def'])
    else:
      filters['sample_time_def'] = params['sample_time_def']

    if params['history'] and params['history'] not in ['TRUE', 'FALSE']:
      raise BadRequest('Invalid value for parameter history: %s' % params['history'])
    else:
      filters['history'] = params['history']

    return filters