def get_cohort(cohort_id): if is_unauthorized_search(request.args): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) include_students = util.to_bool_or_none( util.get(request.args, 'includeStudents')) include_students = True if include_students is None else include_students order_by = util.get(request.args, 'orderBy', None) offset = util.get(request.args, 'offset', 0) limit = util.get(request.args, 'limit', 50) cohort = CohortFilter.find_by_id(int(cohort_id)) if cohort and can_view_cohort(current_user, cohort): cohort = decorate_cohort( cohort, order_by=order_by, offset=int(offset), limit=int(limit), include_alerts_for_uid=current_user.uid, include_profiles=True, include_students=include_students, ) return tolerant_jsonify(cohort) else: raise ResourceNotFoundError( f'No cohort found with identifier: {cohort_id}')
def search_students(): params = request.get_json() if is_unauthorized_search(params): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) search_phrase = util.get(params, 'searchPhrase', '').strip() if not len(search_phrase): raise BadRequestError('Invalid or empty search input') results = search_for_students( include_profiles=True, search_phrase=search_phrase.replace(',', ' '), is_active_asc=_convert_asc_inactive_arg( util.get(params, 'isInactiveAsc')), order_by=util.get(params, 'orderBy', None), offset=util.get(params, 'offset', 0), limit=util.get(params, 'limit', 50), ) alert_counts = Alert.current_alert_counts_for_viewer(current_user.id) students = results['students'] add_alert_counts(alert_counts, students) return tolerant_jsonify({ 'students': students, 'totalStudentCount': results['totalStudentCount'], })
def search(): params = util.remove_none_values(request.get_json()) order_by = util.get(params, 'orderBy', None) if is_unauthorized_search(list(params.keys()), order_by): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) search_phrase = util.get(params, 'searchPhrase', '').strip() domain = { 'students': util.get(params, 'students'), 'courses': util.get(params, 'courses'), 'notes': util.get(params, 'notes'), } if not domain['students'] and not domain['courses'] and not domain['notes']: raise BadRequestError('No search domain specified') if not len(search_phrase) and not domain['notes']: raise BadRequestError('Invalid or empty search input') feed = {} if len(search_phrase) and domain['students']: feed.update(_student_search(search_phrase, params, order_by)) if len(search_phrase) and domain['courses']: feed.update(_course_search(search_phrase, params, order_by)) if domain['notes']: feed.update(_notes_search(search_phrase, params)) return tolerant_jsonify(feed)
def _appointments_search(search_phrase, params): appointment_options = util.get(params, 'appointmentOptions', {}) advisor_uid = appointment_options.get('advisorUid') advisor_csid = appointment_options.get('advisorCsid') student_csid = appointment_options.get('studentCsid') topic = appointment_options.get('topic') limit = int(util.get(appointment_options, 'limit', 20)) offset = int(util.get(appointment_options, 'offset', 0)) date_from = appointment_options.get('dateFrom') date_to = appointment_options.get('dateTo') if not len(search_phrase) and not (advisor_uid or advisor_csid or student_csid or topic or date_from or date_to): raise BadRequestError('Invalid or empty search input') if advisor_csid and not advisor_uid: advisor_uid = get_uid_for_csid(app, advisor_csid) if date_from: try: datetime_from = util.localized_timestamp_to_utc( f'{date_from}T00:00:00') except ValueError: raise BadRequestError('Invalid dateFrom value') else: datetime_from = None if date_to: try: datetime_to = util.localized_timestamp_to_utc( f'{date_to}T00:00:00') + timedelta(days=1) except ValueError: raise BadRequestError('Invalid dateTo value') else: datetime_to = None if datetime_from and datetime_to and datetime_to <= datetime_from: raise BadRequestError('dateFrom must be less than dateTo') appointment_results = search_advising_appointments( search_phrase=search_phrase, advisor_uid=advisor_uid, student_csid=student_csid, topic=topic, datetime_from=datetime_from, datetime_to=datetime_to, offset=offset, limit=limit, ) return { 'appointments': appointment_results, }
def search_admits(): params = request.get_json() search_phrase = util.get(params, 'searchPhrase', '').strip() if not len(search_phrase): raise BadRequestError('Invalid or empty search input') order_by = util.get(params, 'orderBy', None) admit_results = search_for_admitted_students( search_phrase=search_phrase.replace(',', ' '), order_by=order_by, ) return tolerant_jsonify(admit_results)
def _notes_search(search_phrase, params): note_options = util.get(params, 'noteOptions', {}) author_csid = note_options.get('authorCsid') student_csid = note_options.get('studentCsid') topic = note_options.get('topic') limit = util.get(note_options, 'limit', 100) offset = util.get(note_options, 'offset', 0) date_from = note_options.get('dateFrom') date_to = note_options.get('dateTo') if not len(search_phrase) and not (author_csid or student_csid or topic or date_from or date_to): raise BadRequestError('Invalid or empty search input') if date_from: try: datetime_from = util.localized_timestamp_to_utc( f'{date_from}T00:00:00') except ValueError: raise BadRequestError('Invalid dateFrom value') else: datetime_from = None if date_to: try: datetime_to = util.localized_timestamp_to_utc( f'{date_to}T00:00:00') + timedelta(days=1) except ValueError: raise BadRequestError('Invalid dateTo value') else: datetime_to = None if datetime_from and datetime_to and datetime_to <= datetime_from: raise BadRequestError('dateFrom must be less than dateTo') notes_results = search_advising_notes( search_phrase=search_phrase, author_csid=author_csid, student_csid=student_csid, topic=topic, datetime_from=datetime_from, datetime_to=datetime_to, offset=int(offset), limit=int(limit), ) return { 'notes': notes_results, }
def get_section(term_id, section_id): offset = util.get(request.args, 'offset', None) if offset: offset = int(offset) limit = util.get(request.args, 'limit', None) if limit: limit = int(limit) section = get_sis_section(term_id, section_id) if not section: raise ResourceNotFoundError(f'No section {section_id} in term {term_id}') student_profiles = get_course_student_profiles(term_id, section_id, offset=offset, limit=limit) section.update(student_profiles) Alert.include_alert_counts_for_students(viewer_uid=current_user.uid, cohort=student_profiles) return tolerant_jsonify(section)
def create_or_update_user_profile(): params = request.get_json() profile = params.get('profile', None) memberships = params.get('memberships', None) delete_action = to_bool_or_none(util.get(params, 'deleteAction')) if not profile or not profile.get('uid') or memberships is None: raise errors.BadRequestError('Required parameters are missing') authorized_user = _update_or_create_authorized_user(memberships, profile, include_deleted=True) _delete_existing_memberships(authorized_user) _create_department_memberships(authorized_user, memberships) if delete_action is True and not authorized_user.deleted_at: AuthorizedUser.delete(authorized_user.uid) elif delete_action is False and authorized_user.deleted_at: AuthorizedUser.un_delete(authorized_user.uid) user_id = authorized_user.id UserSession.flush_cache_for_id(user_id) updated_user = AuthorizedUser.find_by_id(user_id, include_deleted=True) users_json = authorized_users_api_feed([updated_user]) return tolerant_jsonify(users_json and users_json[0])
def get_admin_users(): params = request.get_json() ignore_deleted = to_bool_or_none(util.get(params, 'ignoreDeleted')) users = AuthorizedUser.get_admin_users( ignore_deleted=True if ignore_deleted is None else ignore_deleted) return tolerant_jsonify({ 'users': authorized_users_api_feed( users, sort_by=util.get(params, 'sortBy'), sort_descending=to_bool_or_none(util.get(params, 'sortDescending')), ), 'totalUserCount': len(users), })
def _student_search(search_phrase, params, order_by): student_results = search_for_students( search_phrase=search_phrase.replace(',', ' '), order_by=order_by, offset=util.get(params, 'offset', 0), limit=util.get(params, 'limit', 50), ) students = student_results['students'] sids = [s['sid'] for s in students] alert_counts = Alert.current_alert_counts_for_sids(current_user.get_id(), sids) add_alert_counts(alert_counts, students) return { 'students': students, 'totalStudentCount': student_results['totalStudentCount'], }
def user_by_uid(uid): ignore_deleted = to_bool_or_none(util.get(request.args, 'ignoreDeleted')) user = _find_user_by_uid(uid, ignore_deleted) if user: users_feed = authorized_users_api_feed([user]) return tolerant_jsonify(users_feed[0]) else: raise errors.ResourceNotFoundError('User not found')
def get_section(term_id, section_id): if not current_user.can_access_canvas_data: raise ForbiddenRequestError('Unauthorized to view course data') offset = util.get(request.args, 'offset', None) if offset: offset = int(offset) limit = util.get(request.args, 'limit', None) if limit: limit = int(limit) featured = util.get(request.args, 'featured', None) section = get_sis_section(term_id, section_id) if not section: raise ResourceNotFoundError(f'No section {section_id} in term {term_id}') student_profiles = get_course_student_profiles(term_id, section_id, offset=offset, limit=limit, featured=featured) section.update(student_profiles) Alert.include_alert_counts_for_students(viewer_user_id=current_user.get_id(), group=student_profiles) return tolerant_jsonify(section)
def get_departments(): exclude_empty = to_bool_or_none( util.get(request.args, 'excludeEmpty', None)) api_json = [] for d in UniversityDept.get_all(exclude_empty=exclude_empty): api_json.append({ 'id': d.id, 'code': d.dept_code, 'name': d.dept_name, }) return tolerant_jsonify(api_json)
def all_users(): params = request.get_json() users, total_user_count = AuthorizedUser.get_users( blocked=to_bool_or_none(util.get(params, 'blocked')), deleted=to_bool_or_none(util.get(params, 'deleted')), dept_code=util.get(params, 'deptCode', None), role=util.get(params, 'role', None) or None, ) return tolerant_jsonify({ 'users': authorized_users_api_feed( users, sort_by=util.get(params, 'sortBy', 'lastName'), sort_descending=to_bool_or_none( util.get(params, 'sortDescending', False)), ), 'totalUserCount': total_user_count, })
def search(): params = util.remove_none_values(request.get_json()) order_by = util.get(params, 'orderBy', None) if is_unauthorized_search(list(params.keys()), order_by): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) search_phrase = util.get(params, 'searchPhrase', '').strip() domain = { 'appointments': util.get(params, 'appointments'), 'students': util.get(params, 'students'), 'courses': util.get(params, 'courses'), 'notes': util.get(params, 'notes'), } if not domain['students'] and not domain['courses'] and not ( domain['notes'] or domain['appointments']): raise BadRequestError('No search domain specified') if not len(search_phrase) and not (domain['notes'] or domain['appointments']): raise BadRequestError('Invalid or empty search input') if domain['courses'] and not current_user.can_access_canvas_data: raise ForbiddenRequestError('Unauthorized to search courses') feed = {} if domain['appointments'] and app.config[ 'FEATURE_FLAG_ADVISOR_APPOINTMENTS']: feed.update(_appointments_search(search_phrase, params)) if len(search_phrase) and domain['students']: feed.update(_student_search(search_phrase, params, order_by)) if len(search_phrase) and domain['courses']: feed.update(_course_search(search_phrase, params, order_by)) if domain['notes']: feed.update(_notes_search(search_phrase, params)) return tolerant_jsonify(feed)
def get_students(): params = request.get_json() if is_unauthorized_search(params): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) results = query_students( advisor_ldap_uids=util.get(params, 'advisorLdapUids'), coe_prep_statuses=util.get(params, 'coePrepStatuses'), ethnicities=util.get(params, 'ethnicities'), genders=util.get(params, 'genders'), gpa_ranges=util.get(params, 'gpaRanges'), group_codes=util.get(params, 'groupCodes'), include_profiles=True, is_active_asc=_convert_asc_inactive_arg( util.get(params, 'isInactiveAsc')), in_intensive_cohort=util.to_bool_or_none( util.get(params, 'inIntensiveCohort')), last_name_range=_get_name_range_boundaries( util.get(params, 'lastNameRange')), levels=util.get(params, 'levels'), limit=util.get(params, 'limit', 50), majors=util.get(params, 'majors'), offset=util.get(params, 'offset', 0), order_by=util.get(params, 'orderBy', None), underrepresented=util.get(params, 'underrepresented'), unit_ranges=util.get(params, 'unitRanges'), ) if results is None: raise BadRequestError('Invalid search criteria') alert_counts = Alert.current_alert_counts_for_viewer(current_user.id) students = results['students'] if results else [] add_alert_counts(alert_counts, students) return tolerant_jsonify({ 'students': students, 'totalStudentCount': results['totalStudentCount'] if results else 0, })
def to_api_json( self, order_by=None, offset=0, limit=50, alert_offset=None, alert_limit=None, include_sids=False, include_students=True, include_profiles=False, include_alerts_for_user_id=None, ): benchmark = get_benchmarker(f'CohortFilter {self.id} to_api_json') benchmark('begin') c = self.filter_criteria c = c if isinstance(c, dict) else json.loads(c) coe_advisor_ldap_uids = util.get(c, 'coeAdvisorLdapUids') if not isinstance(coe_advisor_ldap_uids, list): coe_advisor_ldap_uids = [coe_advisor_ldap_uids ] if coe_advisor_ldap_uids else None cohort_name = self.name cohort_json = { 'id': self.id, 'code': self.id, 'name': cohort_name, 'owners': [], 'alertCount': self.alert_count, } for owner in self.owners: cohort_json['owners'].append({ 'uid': owner.uid, 'deptCodes': [ m.university_dept.dept_code for m in owner.department_memberships ], }) coe_ethnicities = c.get('coeEthnicities') coe_genders = c.get('coeGenders') coe_prep_statuses = c.get('coePrepStatuses') coe_probation = util.to_bool_or_none(c.get('coeProbation')) coe_underrepresented = util.to_bool_or_none( c.get('coeUnderrepresented')) cohort_owner_academic_plans = util.get(c, 'cohortOwnerAcademicPlans') entering_terms = c.get('enteringTerms') ethnicities = c.get('ethnicities') expected_grad_terms = c.get('expectedGradTerms') genders = c.get('genders') gpa_ranges = c.get('gpaRanges') group_codes = c.get('groupCodes') in_intensive_cohort = util.to_bool_or_none(c.get('inIntensiveCohort')) is_inactive_asc = util.to_bool_or_none(c.get('isInactiveAsc')) is_inactive_coe = util.to_bool_or_none(c.get('isInactiveCoe')) last_name_ranges = c.get('lastNameRanges') last_term_gpa_ranges = c.get('lastTermGpaRanges') levels = c.get('levels') majors = c.get('majors') midpoint_deficient_grade = util.to_bool_or_none( c.get('midpointDeficient')) team_groups = athletics.get_team_groups( group_codes) if group_codes else [] transfer = util.to_bool_or_none(c.get('transfer')) underrepresented = util.to_bool_or_none(c.get('underrepresented')) unit_ranges = c.get('unitRanges') cohort_json.update({ 'criteria': { 'coeAdvisorLdapUids': coe_advisor_ldap_uids, 'coeEthnicities': coe_ethnicities, 'coeGenders': coe_genders, 'coePrepStatuses': coe_prep_statuses, 'coeProbation': coe_probation, 'coeUnderrepresented': coe_underrepresented, 'cohortOwnerAcademicPlans': cohort_owner_academic_plans, 'enteringTerms': entering_terms, 'ethnicities': ethnicities, 'expectedGradTerms': expected_grad_terms, 'genders': genders, 'gpaRanges': gpa_ranges, 'groupCodes': group_codes, 'inIntensiveCohort': in_intensive_cohort, 'isInactiveAsc': is_inactive_asc, 'isInactiveCoe': is_inactive_coe, 'lastNameRanges': last_name_ranges, 'lastTermGpaRanges': last_term_gpa_ranges, 'levels': levels, 'majors': majors, 'midpointDeficient': midpoint_deficient_grade, 'transfer': transfer, 'unitRanges': unit_ranges, 'underrepresented': underrepresented, }, 'teamGroups': team_groups, }) if not include_students and not include_alerts_for_user_id and self.student_count is not None: # No need for a students query; return the database-stashed student count. cohort_json.update({ 'totalStudentCount': self.student_count, }) benchmark('end') return cohort_json benchmark('begin students query') sids_only = not include_students # Translate the "My Students" filter, if present, into queryable criteria. Although our database relationships allow # for multiple cohort owners, we assume a single owner here since the "My Students" filter makes no sense # in any other scenario. if cohort_owner_academic_plans: if self.owners: owner_sid = get_csid_for_uid(app, self.owners[0].uid) else: owner_sid = current_user.get_csid() advisor_plan_mappings = [{ 'advisor_sid': owner_sid, 'academic_plan_code': plan } for plan in cohort_owner_academic_plans] else: advisor_plan_mappings = None results = query_students( advisor_plan_mappings=advisor_plan_mappings, coe_advisor_ldap_uids=coe_advisor_ldap_uids, coe_ethnicities=coe_ethnicities, coe_genders=coe_genders, coe_prep_statuses=coe_prep_statuses, coe_probation=coe_probation, coe_underrepresented=coe_underrepresented, entering_terms=entering_terms, ethnicities=ethnicities, expected_grad_terms=expected_grad_terms, genders=genders, gpa_ranges=gpa_ranges, group_codes=group_codes, in_intensive_cohort=in_intensive_cohort, include_profiles=(include_students and include_profiles), is_active_asc=None if is_inactive_asc is None else not is_inactive_asc, is_active_coe=None if is_inactive_coe is None else not is_inactive_coe, last_name_ranges=last_name_ranges, last_term_gpa_ranges=last_term_gpa_ranges, levels=levels, limit=limit, majors=majors, midpoint_deficient_grade=midpoint_deficient_grade, offset=offset, order_by=order_by, sids_only=sids_only, transfer=transfer, underrepresented=underrepresented, unit_ranges=unit_ranges, ) benchmark('end students query') if results: # Cohort might have tens of thousands of SIDs. if include_sids: cohort_json['sids'] = results['sids'] cohort_json.update({ 'totalStudentCount': results['totalStudentCount'], }) # If the cohort is new or cache refresh is underway then store student_count and sids in the db. if self.student_count is None: self.update_sids_and_student_count( results['sids'], results['totalStudentCount']) if include_students: cohort_json.update({ 'students': results['students'], }) if include_alerts_for_user_id: benchmark('begin alerts query') alert_count_per_sid = Alert.include_alert_counts_for_students( viewer_user_id=include_alerts_for_user_id, group=results, offset=alert_offset, limit=alert_limit, ) benchmark('end alerts query') cohort_json.update({ 'alerts': alert_count_per_sid, }) if self.alert_count is None: alert_count = sum(student['alertCount'] for student in alert_count_per_sid) self.update_alert_count(alert_count) cohort_json.update({ 'alertCount': alert_count, }) benchmark('end') return cohort_json
def to_api_json( self, order_by=None, offset=0, limit=50, include_students=True, include_profiles=False, include_alerts_for_uid=None, ): c = self.filter_criteria c = c if isinstance(c, dict) else json.loads(c) advisor_ldap_uids = util.get(c, 'advisorLdapUids') if not isinstance(advisor_ldap_uids, list): advisor_ldap_uids = [advisor_ldap_uids ] if advisor_ldap_uids else None cohort_name = self.label cohort_json = { 'id': self.id, 'code': self.id, 'label': cohort_name, 'name': cohort_name, 'owners': [user.uid for user in self.owners], } coe_prep_statuses = c.get('coePrepStatuses') ethnicities = c.get('ethnicities') genders = c.get('genders') gpa_ranges = c.get('gpaRanges') group_codes = c.get('groupCodes') in_intensive_cohort = util.to_bool_or_none(c.get('inIntensiveCohort')) is_inactive_asc = util.to_bool_or_none(c.get('isInactiveAsc')) last_name_range = c.get('lastNameRange') levels = c.get('levels') majors = c.get('majors') team_groups = athletics.get_team_groups( group_codes) if group_codes else [] underrepresented = util.to_bool_or_none(c.get('underrepresented')) unit_ranges = c.get('unitRanges') cohort_json.update({ 'filterCriteria': { 'advisorLdapUids': advisor_ldap_uids, 'coePrepStatuses': coe_prep_statuses, 'ethnicities': ethnicities, 'genders': genders, 'gpaRanges': gpa_ranges, 'groupCodes': group_codes, 'inIntensiveCohort': in_intensive_cohort, 'isInactiveAsc': is_inactive_asc, 'lastNameRange': last_name_range, 'levels': levels, 'majors': majors, 'unitRanges': unit_ranges, 'underrepresented': underrepresented, }, 'teamGroups': team_groups, }) if not include_students and not include_alerts_for_uid and self.student_count is not None: # No need for a students query; return the database-stashed student count. cohort_json.update({ 'totalStudentCount': self.student_count, }) return cohort_json owner = self.owners[0] if len(self.owners) else None if owner and 'UWASC' in get_dept_codes(owner): is_active_asc = not is_inactive_asc else: is_active_asc = None if is_inactive_asc is None else not is_inactive_asc sids_only = not include_students results = query_students( advisor_ldap_uids=advisor_ldap_uids, coe_prep_statuses=coe_prep_statuses, ethnicities=ethnicities, genders=genders, gpa_ranges=gpa_ranges, group_codes=group_codes, in_intensive_cohort=in_intensive_cohort, include_profiles=(include_students and include_profiles), is_active_asc=is_active_asc, last_name_range=last_name_range, levels=levels, limit=limit, majors=majors, offset=offset, order_by=order_by, sids_only=sids_only, underrepresented=underrepresented, unit_ranges=unit_ranges, ) if results: # If the cohort is newly created or a cache refresh is underway, store the student count in the database # to save future queries. if self.student_count is None: self.update_student_count(results['totalStudentCount']) cohort_json.update({ 'totalStudentCount': results['totalStudentCount'], }) if include_students: cohort_json.update({ 'students': results['students'], }) if include_alerts_for_uid: alert_counts = Alert.include_alert_counts_for_students( viewer_uid=include_alerts_for_uid, cohort=results) cohort_json.update({ 'alerts': alert_counts, }) return cohort_json
def _query_students( benchmark, criteria, include_profiles, limit, offset, order_by, owner, sids_only, term_id, ): benchmark('begin students query') # Translate the "My Students" filter, if present, into queryable criteria. plans = criteria.get('cohortOwnerAcademicPlans') if plans: if owner: owner_sid = get_csid_for_uid(app, owner.uid) else: owner_sid = current_user.get_csid() advisor_plan_mappings = [{ 'advisor_sid': owner_sid, 'academic_plan_code': plan } for plan in plans] else: advisor_plan_mappings = None coe_advisor_ldap_uids = util.get(criteria, 'coeAdvisorLdapUids') if not isinstance(coe_advisor_ldap_uids, list): coe_advisor_ldap_uids = [coe_advisor_ldap_uids ] if coe_advisor_ldap_uids else None results = query_students( academic_standings=criteria.get('academicStandings'), advisor_plan_mappings=advisor_plan_mappings, coe_advisor_ldap_uids=coe_advisor_ldap_uids, coe_ethnicities=criteria.get('coeEthnicities'), coe_genders=criteria.get('coeGenders'), coe_prep_statuses=criteria.get('coePrepStatuses'), coe_probation=criteria.get('coeProbation'), coe_underrepresented=criteria.get('coeUnderrepresented'), colleges=criteria.get('colleges'), curated_group_ids=criteria.get('curatedGroupIds'), entering_terms=criteria.get('enteringTerms'), epn_cpn_grading_terms=criteria.get('epnCpnGradingTerms'), ethnicities=criteria.get('ethnicities'), expected_grad_terms=criteria.get('expectedGradTerms'), genders=criteria.get('genders'), gpa_ranges=criteria.get('gpaRanges'), group_codes=criteria.get('groupCodes'), in_intensive_cohort=criteria.get('inIntensiveCohort'), include_profiles=include_profiles, intended_majors=criteria.get('intendedMajors'), is_active_asc=None if criteria.get('isInactiveAsc') is None else not criteria.get('isInactiveAsc'), is_active_coe=None if criteria.get('isInactiveCoe') is None else not criteria.get('isInactiveCoe'), last_name_ranges=criteria.get('lastNameRanges'), last_term_gpa_ranges=criteria.get('lastTermGpaRanges'), levels=criteria.get('levels'), limit=limit, majors=criteria.get('majors'), midpoint_deficient_grade=criteria.get('midpointDeficient'), minors=criteria.get('minors'), offset=offset, order_by=order_by, sids_only=sids_only, term_id=term_id, transfer=criteria.get('transfer'), underrepresented=criteria.get('underrepresented'), unit_ranges=criteria.get('unitRanges'), visa_types=criteria.get('visaTypes'), student_holds=criteria.get('studentHolds'), ) benchmark('end students query') return results
def authorized_user_groups(): sort_users_by = util.get(request.args, 'sortUsersBy', None) return tolerant_jsonify(_get_boa_user_groups(sort_users_by))
def all_users(): sort_users_by = util.get(request.args, 'sortUsersBy', None) return tolerant_jsonify(_get_boa_users(sort_users_by))
def create_cohort(): params = request.get_json() if is_unauthorized_search(params): raise ForbiddenRequestError( 'You are unauthorized to access student data managed by other departments' ) label = util.get(params, 'label', None) if not label: raise BadRequestError('Cohort creation requires \'label\'') cohort = CohortFilter.create( advisor_ldap_uids=util.get(params, 'advisorLdapUids'), coe_prep_statuses=util.get(params, 'coePrepStatuses'), ethnicities=util.get(params, 'ethnicities'), genders=util.get(params, 'genders'), gpa_ranges=util.get(params, 'gpaRanges'), group_codes=util.get(params, 'groupCodes'), in_intensive_cohort=util.to_bool_or_none( params.get('inIntensiveCohort')), is_inactive_asc=util.to_bool_or_none(params.get('isInactiveAsc')), label=label, last_name_range=util.get(params, 'lastNameRange'), levels=util.get(params, 'levels'), majors=util.get(params, 'majors'), uid=current_user.get_id(), underrepresented=util.get(params, 'underrepresented'), unit_ranges=util.get(params, 'unitRanges'), ) return tolerant_jsonify(decorate_cohort(cohort))