class Query(ObjectType): class Meta: exclude_fields = ('users', 'wishlists', 'items', 'groups') node = relay.Node.Field() me = Field(UserQl, description="Return yourself by ID from token") user = Field(UserQl, user_id=ID(required=True), description="Return user by ID") wishlist = Field(WishlistQl, list_id=ID(required=True), description="Return wishlist by ID") get_all_user_lists = List( WishlistQl, user_id=ID(required=True), description="Return all wishlists of the user by his ID") item = Field(ItemQl, item_id=ID(required=True), description="Return item by ID") group = Field(GroupQl, group_id=ID(required=True), description="Return group by ID") news = Field(lambda: List(WaIQL), description="News from friends of user") index = Field( lambda: List(WaIQL), description="All open items and wishlists of all users on this service" ) search = Field( lambda: List(SearchQL), search_text=String(required=True), description= "Search in nicknames, usernames and surnames of users and titles of items, wishlists and groups" ) @token_check @last_seen_set async def resolve_me(parent, info, id_from_token): if id_from_token == 0: raise Exception("For returning yourself token required!") return db.query(UserDB).filter_by(id=int(id_from_token)).first() @last_seen_set async def resolve_user(parent, info, user_id): return db.query(UserDB).filter_by(id=int(user_id)).first() @token_check @last_seen_set async def resolve_wishlist(parent, info, list_id, id_from_token): wishlist = db.query(WishlistDB).filter_by(id=int(list_id)).first() if wishlist.access_level == AccessLevelEnum.ALL: return wishlist if wishlist.access_level == AccessLevelEnum.NOBODY and wishlist.user_id == id_from_token: return wishlist if wishlist.access_level == AccessLevelEnum.FRIENDS and db.query( FSDB).filter_by(user_id_1=wishlist.user_id, user_id_2=id_from_token).first(): return wishlist raise Exception("Access denied!") @token_check @last_seen_set async def resolve_get_all_user_lists(parent, info, user_id, id_from_token): response = list() wishlists = db.query(WishlistDB).filter_by(user_id=int(user_id)).all() if len(wishlists) == 0: return wishlists for wlist in wishlists: if wlist.access_level == AccessLevelEnum.ALL: response.append(wlist) if wlist.access_level == AccessLevelEnum.NOBODY and wlist.user_id == id_from_token: response.append(wlist) if wlist.access_level == AccessLevelEnum.FRIENDS and db.query( FSBD).filter_by(user_id_1=wlist.user_id, user_id_2=id_from_token).first(): response.append(wlist) if len(response) > 0: return response return [] @token_check @last_seen_set async def resolve_item(parent, info, item_id, id_from_token): item = db.query(ItemDB).filter_by(id=int(item_id)).first() if item.access_level == AccessLevelEnum.ALL: return item if item.access_level == AccessLevelEnum.NOBODY and item.owner_id == id_from_token: return item if item.access_level == AccessLevelEnum.FRIENDS and db.query( FSDB).filter_by(user_id_1=item.owner_id, user_id_2=id_from_token).first(): return item raise Exception("Access denied!") @token_check @last_seen_set async def resolve_group(parent, info, group_id, id_from_token): group = db.query(GroupDB).filter_by(id=group_id).first() if group.access_level == GroupAccessEnum.OPEN: return group user_group = db.query(GroupUserDB).filter_by( user_id=id_from_token, group_id=group_id).first() if group.access_level == GroupAccessEnum.CLOSE and user_group is not None: return group raise Exception("Access denied!") @token_check @last_seen_set async def resolve_news(parent, info, id_from_token): wishlists = db.query(WishlistDB)\ .join(WishlistDB.user_owner)\ .join(UserDB.friends)\ .filter(and_(UserDB.id == id_from_token, or_((WishlistDB.access_level == 'ALL'), (WishlistDB.access_level == 'FRIENDS'))))\ .all() items = db.query(ItemDB)\ .join(ItemDB.owner)\ .join(UserDB.friends) \ .filter(and_(UserDB.id == id_from_token, or_((ItemDB.access_level == 'ALL'), (ItemDB.access_level == 'FRIENDS'))))\ .all() return items + wishlists @last_seen_set async def resolve_index(parent, info): wishlists = db.query(WishlistDB) \ .join(WishlistDB.user_owner) \ .join(UserDB.friends) \ .filter(WishlistDB.access_level == 'ALL') \ .all() items = db.query(ItemDB) \ .join(ItemDB.owner) \ .join(UserDB.friends) \ .filter(ItemDB.access_level == 'ALL') \ .all() return items + wishlists @token_check @last_seen_set async def resolve_search(parent, info, search_text, id_from_token): string_list = search_text.split(" ") items = list() wishlists = list() users = list() for i in string_list: temp = db.query(UserDB).filter_by(nickname=i).first() if temp is not None: users.append(temp) temp = db.query(UserDB).filter_by(user_name=i).first() if temp is not None: users.append(temp) temp = db.query(UserDB).filter_by(surname=i).first() if temp is not None: users.append(temp) temp = db.query(WishlistDB).filter_by(title=i, access_level='ALL').all() if len(temp) != 0: for j in temp: items.append(j) temp = db.query(ItemDB).filter_by(title=i, access_level='ALL').all() if len(temp) != 0: for j in temp: items.append(j) return items + wishlists + users
class SimulationResults(ObjectType): run_id = ID(required=True) finished = Boolean(required=True) end_date = String(required=True) predicted_metrics = Field(DailyMetrics, required=True)
class UserStatus(ObjectType): status = Field(AuthStatus) preferences = Field(Preferences, required=False)
class Sub(ObjectType): name = String() votes = Field(Votes)
class Query(ObjectType): available_events = List(Event) active_events = List(Event) simulation_results = Field(SimulationResults, run_id=ID(required=True)) validation_metrics = Field(DailyMetrics) scenarios = List(Scenario) mobility_change_metrics = Field(DailyMetrics) area = Field(SimulationArea) def resolve_available_events(query, info): out = [] for iv in INTERVENTIONS: out.append(iv_to_graphql_obj(iv)) return out def resolve_active_events(query, info): interventions = get_active_interventions() out = [] for idx, iv in enumerate(interventions): obj = iv_to_graphql_obj(iv, obj_id=idx) out.append(obj) return out def resolve_simulation_results(query, info, run_id): cache_key = '%s-finished' % run_id finished = cache.get(cache_key) if finished is None: raise GraphQLError('No simulation run active') if finished and run_id in simulation_processes: print('Process %s finished, joining' % run_id) process = simulation_processes[run_id] if process.is_alive(): print('Process is still alive??') simulation_processes[run_id].kill() simulation_processes[run_id].join() del simulation_processes[run_id] error = cache.get('%s-error' % run_id) if error is not None: raise GraphQLError('Simulation error: %s' % error) results = cache.get('%s-results' % run_id) if results is not None: dates, metrics = results_to_metrics(results) else: dates = [] metrics = [] daily_metrics = DailyMetrics(dates=dates, metrics=metrics) return SimulationResults(run_id=run_id, finished=finished, predicted_metrics=daily_metrics) def resolve_validation_metrics(query, info): df = get_detected_cases() sim_start = date.fromisoformat(get_variable('start_date')) sim_end = sim_start + timedelta(days=get_variable('simulation_days')) df = df[df.index < sim_end] df['detected'] = df['all_detected'].diff() df['detected'] = df['detected'].rolling(window=14).mean().round().astype('Int64').replace({np.nan: None}) dates = df.index.astype(str).values metrics = [] for col in df.columns: m = get_metric(col) if not m: raise Exception('no metric found for %s' % col) int_values = df[col].to_numpy() metrics.append( Metric( type=m.id, label=m.label, description=m.description, unit=m.unit, color=m.color, is_integer=m.is_integer, is_simulated=False, int_values=int_values ) ) return DailyMetrics(dates=dates, metrics=metrics) def resolve_mobility_change_metrics(self, info): df = get_mobility_data().rolling(7).mean().round().dropna(how='all') df = df.astype('Int32').replace({np.nan: None}) metrics = [] dates = list(df.index.astype(str).values) for col in df: s = df[col] m = get_metric('%s_mobility_change' % col) m_obj = Metric( type=m.id, label=m.label, description=m.description, unit=m.unit, color=m.color, is_integer=m.is_integer, is_simulated=False, int_values=s.values, ) metrics.append(m_obj) return DailyMetrics(dates=dates, metrics=metrics) def resolve_area(query, info): name = get_variable('area_name') name_long = get_variable('area_name_long') s = get_age_grouped_population() total = s.sum() age_groups = [dict(label=x, count=y) for x, y in zip(s.index, s)] return dict( name=name, name_long=name_long, total_population=total, age_groups=age_groups, ) def resolve_scenarios(query, info): scenarios = get_variable('scenarios') active_scenario = get_variable('active_scenario') out = [] customized_variables = list(get_session_variables().keys()) if 'active_scenario' in customized_variables: customized_variables.remove('active_scenario') if len(customized_variables): customized = True else: customized = False for s in scenarios: if s['id'] == active_scenario and not customized: active = True else: active = False out.append(Scenario( id=s['id'], label=s['label'], description=s['description'], active=active )) return out
class Query(ObjectType): pet = Field(Pet)
class Stats(ObjectType): votes = Field(VotesStats) bots = Field(BotsStats)
class Meta: model = Reporter custom_option = 'custom_option' custom_fields = OrderedDict([('custom_field', Field(Int()))])
# Params used to limit what locations are available to the Region # We don't add filter fields at this level. The filter fields start at search_location.data, search_location.geojson, # etc. We don't want a search_location.dataContains field as part of the SearchLocationType class # The sample user search data fields for rescape-region. This must be overridden in applications # that use rescape-region user_search_location_data_fields = dict( searchLocation=dict( type=SearchLocationType, graphene_type=SearchLocationType, fields=search_location_fields, # References the model class type_modifier=lambda *type_and_args: Field( *type_and_args, resolver=model_resolver_for_dict_field(SearchLocation))), # Indicates if this SearchLocation is active for the user activity=dict( type=ActivityDataType, graphene_type=ActivityDataType, fields=activity_data_fields, type_modifier=lambda *type_and_args: Field( *type_and_args, resolver=resolver_for_dict_field), )) UserSearchLocationDataType = type( 'UserSearchLocationDataType', (ObjectType, ), type_modify_fields(user_search_location_data_fields), )
class CategorySetPeriodTotalType(ObjectType): period_totals = List(PeriodTotalType) set = CategorySet() group = Field(CategoryGroupType)
class DateRangeQuery(ObjectType): date_range = Field(DateRangeType) def resolve_date_range(self, info, **kwargs): return date_start_end(info.context.user)
class CategoryPeriodTotalType(ObjectType): period_totals = List(PeriodTotalType) category = Field(CategoryType)
class CategoryTotalType(graphene.ObjectType): total = Float() category = Field(CategoryType)
class InfrastructureQueryInput(InputObjectType): location = Field(Location, required=True) radius = Int(default_value=50000) amount = Int(required=True) infrastructure = String()
class Query(ObjectType): get_person = Field(Person, name=String()) def resolve_get_person(self, info, name): # Person object/ class that has the same properties return Person(name=name)
class Query(object): account_note = Field(AccountNoteType, note_id=ID()) student = Field(StudentType, user_id=ID(), email=String()) school = Field(SchoolType, school_id=ID(), name=String()) parent = Field(ParentType, user_id=ID(), email=String()) instructor = Field(InstructorType, user_id=ID(), email=String()) admin = Field(AdminType, user_id=ID(), email=String()) user_info = Field(UserInfoType, user_id=ID(), user_name=String()) user_type = Field( UserTypeAuth, user_id=ID(), user_name=String(), admin_types=Boolean() ) email_from_token = Field(String, token=String()) verify_google_oauth = Field( GoogleVerifyTokenType, login_email=String(required=True), oauth_email=String(required=True), ) account_notes = List(AccountNoteType, user_id=ID(required=True)) students = List(StudentType, grade=ID()) schools = List(SchoolType, district=String()) parents = List(ParentType) instructors = List(InstructorType, subject=String()) admins = List(AdminType, admin_type=String()) user_infos = List(UserInfoType, user_ids=List(ID)) instructor_ooo = List(InstructorOutOfOfficeType, instructor_id=ID(required=True)) instructor_availability = List( InstructorAvailabilityType, instructor_id=ID(required=True) ) @login_required def resolve_account_note(self, info, **kwargs): note_id = kwargs.get("note_id") if note_id: return AccountNote.objects.get(id=note_id) return None @login_required def resolve_student(self, info, **kwargs): user_id = kwargs.get("user_id") email = kwargs.get("email") if user_id: return Student.objects.get(user=user_id) if email: return Student.objects.get(user__email=email) return None @login_required def resolve_school(self, info, **kwargs): school_id = kwargs.get("school_id") name = kwargs.get("name") if school_id: return School.objects.get(id=school_id) if name: return School.objects.get(name=name) return None @login_required def resolve_parent(self, info, **kwargs): user_id = kwargs.get("user_id") email = kwargs.get("email") if user_id: return Parent.objects.get(user=user_id) if email: return Parent.objects.get(user__email=email) return None @login_required def resolve_instructor(self, info, **kwargs): user_id = kwargs.get("user_id") email = kwargs.get("email") if user_id: return Instructor.objects.get(user=user_id) if email: return Instructor.objects.get(user__email=email) return None @login_required def resolve_admin(self, info, **kwargs): user_id = kwargs.get("user_id") email = kwargs.get("email") if user_id: return Admin.objects.get(user=user_id) if email: return Admin.objects.get(user__email=email) return None def resolve_user_type(self, info, **kwargs): user_id = kwargs.get("user_id") user_name = kwargs.get("user_name") admin_types = kwargs.get("admin_types") if user_name: if Student.objects.filter(user__email=user_name).exists(): return UserTypeAuth(user_type="STUDENT", google_auth_enabled=False) if Instructor.objects.filter(user__email=user_name).exists(): return UserTypeAuth(user_type="INSTRUCTOR", google_auth_enabled=False) if Parent.objects.filter(user__email=user_name).exists(): return UserTypeAuth(user_type="PARENT", google_auth_enabled=False) if Admin.objects.filter(user__email=user_name).exists(): admin = Admin.objects.get(user__email=user_name) if admin_types: return Admin.objects.get(user__email=user_name).admin_type.upper() return UserTypeAuth( user_type="ADMIN", google_auth_enabled=admin.google_auth_enabled ) if user_id: if Student.objects.filter(user=user_id).exists(): return UserTypeAuth(user_type="STUDENT", google_auth_enabled=False) if Instructor.objects.filter(user=user_id).exists(): return UserTypeAuth(user_type="INSTRUCTOR", google_auth_enabled=False) if Parent.objects.filter(user=user_id).exists(): return UserTypeAuth(user_type="PARENT", google_auth_enabled=False) if Admin.objects.filter(user=user_id).exists(): admin = Admin.objects.get(user__email=user_name) if admin_types: return UserTypeAuth( user_type=admin.admin_type.upper(), google_auth_enabled=admin.google_auth_enabled, ) return UserTypeAuth( user_type="ADMIN", google_auth_enabled=admin.google_auth_enabled ) return None @login_required def resolve_user_info(self, info, **kwargs): user_id = kwargs.get("user_id") user_name = kwargs.get("user_name") if user_name: if Student.objects.filter(user__email=user_name).exists(): return Student.objects.get(user__email=user_name) if Instructor.objects.filter(user__email=user_name).exists(): return Instructor.objects.get(user__email=user_name) if Parent.objects.filter(user__email=user_name).exists(): return Parent.objects.get(user__email=user_name) if Admin.objects.filter(user__email=user_name).exists(): return Admin.objects.get(user__email=user_name) if user_id: if Student.objects.filter(user=user_id).exists(): return Student.objects.get(user=user_id) if Instructor.objects.filter(user=user_id).exists(): return Instructor.objects.get(user=user_id) if Parent.objects.filter(user=user_id).exists(): return Parent.objects.get(user=user_id) if Admin.objects.filter(user=user_id).exists(): return Admin.objects.get(user=user_id) return None @login_required def resolve_account_notes(self, info, **kwargs): user_id = kwargs.get("user_id") return AccountNote.objects.filter(user=user_id) def resolve_students(self, info, **kwargs): grade = kwargs.get("grade") if grade: return Student.objects.filter(grade=grade) return Student.objects.all() @login_required def resolve_schools(self, info, **kwargs): district = kwargs.get("district") queryset = School.objects if district: queryset = queryset.filter(district=district) return queryset.all() @login_required def resolve_admins(self, info, **kwargs): admin_type = kwargs.get("admin_type") if admin_type: return Admin.objects.filter(admin_type=admin_type) return Admin.objects.all() @login_required def resolve_parents(self, info, **kwargs): return Parent.objects.all() @login_required def resolve_instructors(self, info, **kwargs): return Instructor.objects.all() @login_required def resolve_instructor_ooo(self, info, **kwargs): instructor_id = kwargs.get("instructor_id") return InstructorOutOfOffice.objects.filter(instructor=instructor_id) @login_required def resolve_instructor_availability(self, info, **kwargs): instructor_id = kwargs.get("instructor_id") return InstructorAvailability.objects.filter(instructor=instructor_id) def resolve_user_infos(self, info, user_ids): user_list = [] for user_id in user_ids: if Student.objects.filter(user=user_id).exists(): user_list.append(Student.objects.get(user=user_id)) if Instructor.objects.filter(user=user_id).exists(): user_list.append(Instructor.objects.get(user=user_id)) if Parent.objects.filter(user=user_id).exists(): user_list.append(Parent.objects.get(user=user_id)) if Admin.objects.filter(user=user_id).exists(): user_list.append(Admin.objects.get(user=user_id)) return user_list def resolve_email_from_token(self, info, token): return jwt.decode(token, settings.SECRET_KEY, algorithms=["HS256"])["email"] def resolve_verify_google_oauth(self, info, login_email, oauth_email): admin = Admin.objects.get(user__email=login_email) if admin.google_auth_email == oauth_email: encoded_jwt = jwt.encode( { "username": login_email, "origIat": int(datetime.utcnow().timestamp()), "exp": int((datetime.utcnow() + timedelta(minutes=5)).timestamp()), }, settings.SECRET_KEY, algorithm="HS256", ) return GoogleVerifyTokenType( token=encoded_jwt.decode("utf-8"), verified=True ) return GoogleVerifyTokenType(token="", verified=False)
def register(self): Dataset.extend( 'rows', Field(List(List(String)), args={'columns': List(String)}), resolve_rows)
def create_user_state_config(class_config): """ Creates the UserStateType based on specific class_config :param class_config: A dict containing class configurations. The default is: dict( settings=dict( model_class=Settings, graphene_class=SettingsType, graphene_fields=settings_fields, query=SettingsQuery, mutation=SettingsMutation ), region=dict( model_class=Region, graphene_class=RegionType, graphene_fields=region_fields, query=RegionQuery, mutation=RegionMutation ), project=dict( model_class=Project, graphene_class=ProjectType, graphene_fields=project_fields, query=ProjectQuery, mutation=ProjectMutation ), resource=dict( model_class=Resource, graphene_class=ResourceType, graphene_fields=resource_fields, query=ResourceQuery, mutation=ResourceMutation ), location=get_location_schema(), user_search=get_user_search_data_schema(), search_location=get_search_location_schema() # additional_user_scope_schemas and additional_user_scopes # are passed in from a calling app # these are a dict of properties that need to go on user_regions and user_projects # at the same level as userSearch. For instance, a user's saved app selections could go here # additional_user_scope_schemas = dict( # userDesignFeatureLayers=dict( # graphene_class=UserDesignFeatureDataType, # graphene_fields=user_design_feature_data_fields # ) # additional_user_scopes explains the path to Django models within additional_user_scope_schemas # additional_django_model_user_scopes = dict( # userDesignFeatureLayers=dict( # designFeature=True # ) # Would match the list of some django DesignFeature model instances ) :return: """ class UserStateType(DjangoObjectType, DjangoObjectTypeRevisionedMixin): """ UserStateType models UserState, which represents the settings both imposed upon and chosen by the user """ id = graphene.Int(source='pk') class Meta: model = UserState # Modify data field to use the resolver. # I guess there's no way to specify a resolver upon field creation, since graphene just reads the underlying # Django model to generate the fields UserStateType._meta.fields['data'] = Field( UserStateDataType(class_config), resolver=resolver_for_data_field ) user_state_fields = merge_with_django_properties(UserStateType, dict( id=dict(create=DENY, update=REQUIRE), # This is a Foreign Key. Graphene generates these relationships for us, but we need it here to # support our Mutation subclasses and query_argument generation # For simplicity we limit fields to id. Mutations can only use id, and a query doesn't need other # details of the User--it can query separately for that user=dict(graphene_type=UserType, fields=user_fields), # This refers to the UserState, which is a representation of all the json fields of UserState.data data=dict(graphene_type=UserStateDataType(class_config), fields=user_state_data_fields(class_config), default=lambda: dict()), **reversion_and_safe_delete_types )) user_state_mutation_config = dict( class_name='UserState', crud={ CREATE: 'createUserState', UPDATE: 'updateUserState' }, resolve=guess_update_or_create ) additional_django_model_user_scopes = R.prop('additional_django_model_user_scopes', class_config) \ if R.prop_or(None, 'additional_django_model_user_scopes', class_config) else {} additional_user_scope_schemas = R.prop('additional_user_scope_schemas', class_config) \ if R.prop_or(None, 'additional_user_scope_schemas', class_config) else {} # The scope instance types expected in user_state.data user_state_scope_instances_config = R.concat([ # dict(region=True) means search all userRegions for that dict dict(pick=dict(userRegions=dict(region=True)), key='region', model=get_region_model() ), # dict(project=True) means search all userProjects for that dict dict( pick=dict(userProjects=dict(project=True)), key='project', model=get_project_model(), # This is currently just needed for the field key's unique_with function field_config=project_fields, # Projects can be modified when userState is mutated can_mutate_related=True ), dict( pick=dict( userRegions=[ dict( userSearch=dict( # dict(searchLocation=True) means search all userSearchLocations for that dict userSearchLocations=dict( searchLocation=True, ) ) ) ], userProjects=[ dict( userSearch=dict( # dict(searchLocation=True) means search all userSearchLocations for that dict userSearchLocations=dict(searchLocation=True) ) ) ] ), key='searchLocation', model=get_search_location_schema()['model_class'], # These can be modified when userState is mutated can_mutate_related=True ), ], # Map each additional_django_model_user_scopes to a scope config R.map_with_obj_to_values( lambda field_name, additional_django_model_user_scope: dict( pick=dict( userRegions=[ {field_name: additional_django_model_user_scope} ], userProjects=[ {field_name: additional_django_model_user_scope} ] ), # Assume the scope object is the deepest field key=list(R.keys(R.flatten_dct(additional_django_model_user_scope, '.')))[0].split('.')[-1], # model isn't needed unless can_mutate_related is true model=additional_user_scope_schemas[field_name]['model'], # These can be modified when userState is mutated can_mutate_related=R.prop_or(False, 'can_mutate_related', additional_django_model_user_scope) ), additional_django_model_user_scopes ) ) class UpsertUserState(Mutation): """ Abstract base class for mutation """ user_state = Field(UserStateType) def mutate(self, info, user_state_data=None): """ Update or create the user state :param info: :param user_state_data: :return: """ # Check that all the scope instances in user_state.data exist. We permit deleted instances for now. new_data = R.prop_or({}, 'data', user_state_data) # Copy since Graphene reuses this data copied_new_data = copy.deepcopy(new_data) old_user_state_data = UserState.objects.get( id=user_state_data['id'] ).data if R.prop_or(None, 'id', user_state_data) else None # Inspect the data and find all scope instances within UserState.data # This includes userRegions[*].region, userProject[*].project and within userRegions and userProjects # userSearch.userSearchLocations[*].search_location and whatever the implementing libraries define # in addition updated_new_data = validate_and_mutate_scope_instances( user_state_scope_instances_config, copied_new_data ) # If either userProjects or userRegions are null, it means those scope instances aren't part # of the update, so merge in the old values if R.prop_or(None, 'id', user_state_data) and R.any_satisfy( lambda user_scope_key: not R.prop_or(None, user_scope_key, updated_new_data), ['userProjects', 'userRegions'] ): # The special update case where one userScope collection is null, # indicates that we are only updating one userScope object. The rest # should remain the same and not be removed for user_scope_key in ['userProjects', 'userRegions']: # Database values old_user_scopes_by_id = user_scope_instances_by_id( user_scope_key, old_user_state_data ) # New values with updates applied new_user_scopes_by_id = user_scope_instances_by_id( user_scope_key, updated_new_data ) # Prefer the old over the new, merging all objects but overriding lists # We override lists because a non-null list always replaces the old list in the database updated_new_data[user_scope_key] = R.values(R.merge_deep( old_user_scopes_by_id, new_user_scopes_by_id, MyMerger( # pass in a list of tuples,with the # strategies you are looking to apply # to each type. [ (list, ["override_non_null"]), (dict, ["merge"]) ], # next, choose the fallback strategies, # applied to all other types: ["override"], # finally, choose the strategies in # the case where the types conflict: ["override"] ) )) # Update user_state_data the updated data modified_user_state_data = R.merge(user_state_data, dict(data=updated_new_data)) # id or user.id can be used to identify the existing instance id_props = R.compact_dict( dict( id=R.prop_or(None, 'id', modified_user_state_data), user_id=R.item_str_path_or(None, 'user.id', modified_user_state_data) ) ) def fetch_and_merge(modified_user_state_data, props): existing = UserState.objects.filter(**props) # If the user doesn't have a user state yet if not R.length(existing): return modified_user_state_data return merge_data_fields_on_update( ['data'], R.head(existing), # Merge existing's id in case it wasn't in user_state_data R.merge(modified_user_state_data, R.pick(['id'], existing)) ) modified_data = R.if_else( R.compose(R.length, R.keys), lambda props: fetch_and_merge(modified_user_state_data, props), lambda _: modified_user_state_data )(id_props) update_or_create_values = input_type_parameters_for_update_or_create( user_state_fields, # Make sure that all props are unique that must be, either by modifying values or erring. enforce_unique_props( user_state_fields, modified_data) ) user_state, created = update_or_create_with_revision(UserState, update_or_create_values) return UpsertUserState(user_state=user_state) class CreateUserState(UpsertUserState): """ Create UserState mutation class """ class Arguments: user_state_data = type('CreateUserStateInputType', (InputObjectType,), input_type_fields(user_state_fields, CREATE, UserStateType) )(required=True) class UpdateUserState(UpsertUserState): """ Update UserState mutation class """ class Arguments: user_state_data = type('UpdateUserStateInputType', (InputObjectType,), input_type_fields(user_state_fields, UPDATE, UserStateType))(required=True) graphql_update_or_create_user_state = graphql_update_or_create(user_state_mutation_config, user_state_fields) graphql_query_user_states = graphql_query(UserStateType, user_state_fields, 'userStates') return dict( model_class=UserState, graphene_class=UserStateType, graphene_fields=user_state_fields, create_mutation_class=CreateUserState, update_mutation_class=UpdateUserState, graphql_mutation=graphql_update_or_create_user_state, graphql_query=graphql_query_user_states )
class Query(ObjectType): pet = Field(PetModelKind)
class UpsertUserState(Mutation): """ Abstract base class for mutation """ user_state = Field(UserStateType) def mutate(self, info, user_state_data=None): """ Update or create the user state :param info: :param user_state_data: :return: """ # Check that all the scope instances in user_state.data exist. We permit deleted instances for now. new_data = R.prop_or({}, 'data', user_state_data) # Copy since Graphene reuses this data copied_new_data = copy.deepcopy(new_data) old_user_state_data = UserState.objects.get( id=user_state_data['id'] ).data if R.prop_or(None, 'id', user_state_data) else None # Inspect the data and find all scope instances within UserState.data # This includes userRegions[*].region, userProject[*].project and within userRegions and userProjects # userSearch.userSearchLocations[*].search_location and whatever the implementing libraries define # in addition updated_new_data = validate_and_mutate_scope_instances( user_state_scope_instances_config, copied_new_data ) # If either userProjects or userRegions are null, it means those scope instances aren't part # of the update, so merge in the old values if R.prop_or(None, 'id', user_state_data) and R.any_satisfy( lambda user_scope_key: not R.prop_or(None, user_scope_key, updated_new_data), ['userProjects', 'userRegions'] ): # The special update case where one userScope collection is null, # indicates that we are only updating one userScope object. The rest # should remain the same and not be removed for user_scope_key in ['userProjects', 'userRegions']: # Database values old_user_scopes_by_id = user_scope_instances_by_id( user_scope_key, old_user_state_data ) # New values with updates applied new_user_scopes_by_id = user_scope_instances_by_id( user_scope_key, updated_new_data ) # Prefer the old over the new, merging all objects but overriding lists # We override lists because a non-null list always replaces the old list in the database updated_new_data[user_scope_key] = R.values(R.merge_deep( old_user_scopes_by_id, new_user_scopes_by_id, MyMerger( # pass in a list of tuples,with the # strategies you are looking to apply # to each type. [ (list, ["override_non_null"]), (dict, ["merge"]) ], # next, choose the fallback strategies, # applied to all other types: ["override"], # finally, choose the strategies in # the case where the types conflict: ["override"] ) )) # Update user_state_data the updated data modified_user_state_data = R.merge(user_state_data, dict(data=updated_new_data)) # id or user.id can be used to identify the existing instance id_props = R.compact_dict( dict( id=R.prop_or(None, 'id', modified_user_state_data), user_id=R.item_str_path_or(None, 'user.id', modified_user_state_data) ) ) def fetch_and_merge(modified_user_state_data, props): existing = UserState.objects.filter(**props) # If the user doesn't have a user state yet if not R.length(existing): return modified_user_state_data return merge_data_fields_on_update( ['data'], R.head(existing), # Merge existing's id in case it wasn't in user_state_data R.merge(modified_user_state_data, R.pick(['id'], existing)) ) modified_data = R.if_else( R.compose(R.length, R.keys), lambda props: fetch_and_merge(modified_user_state_data, props), lambda _: modified_user_state_data )(id_props) update_or_create_values = input_type_parameters_for_update_or_create( user_state_fields, # Make sure that all props are unique that must be, either by modifying values or erring. enforce_unique_props( user_state_fields, modified_data) ) user_state, created = update_or_create_with_revision(UserState, update_or_create_values) return UpsertUserState(user_state=user_state)
class Bot(ObjectType): rank = Int() name = String() score = Float() votes = Field(Votes) karma = Field(Karma)
class PetMutation(DjangoModelFormMutation): pet = Field(pet_type) class Meta: form_class = PetForm
class UserMutation(DjangoModelFormMutation): user = Field(UserType) class Meta: form_class = SignUpForm
class EdgeBase(object): node = Field(cls._meta.node, description='The item at the end of the edge', required=True) cursor = String(required=True, description='A cursor for use in pagination')
class EventChoiceParameter(ObjectType): choices = List(Choice, required=True) choice = Field(Choice) class Meta: interfaces = (EventParameter, )
def convert_ndb_json_property(ndb_prop, registry=None): return Field(JSONString, description=ndb_prop._name)
class EditUser(Mutation): """Edit user of a given project.""" class Arguments(): project_name = String(required=True) email = String(required=True) organization = String(required=True) responsibility = String(required=True) role = String(required=True) phone_number = String(required=True) modified_user = Field(User) success = Boolean() @require_login @enforce_authz @require_project_access def mutate(self, info, **query_args): project_name = query_args.get('project_name') success = False user_data = util.get_jwt_content(info.context) role = get_user_role(user_data) modified_user_data = { 'email': query_args.get('email'), 'organization': query_args.get('organization'), 'responsibility': query_args.get('responsibility'), 'role': query_args.get('role'), 'phone_number': query_args.get('phone_number') } if (role == 'admin' and modified_user_data['role'] in ['admin', 'analyst', 'customer', 'customeradmin']) \ or (is_customeradmin(project_name, user_data['user_email']) and modified_user_data['role'] in ['customer', 'customeradmin']): if user_domain.assign_role(modified_user_data['email'], modified_user_data['role']): modify_user_information(info.context, modified_user_data, project_name) success = True else: rollbar.report_message('Error: Couldn\'t update user role', 'error', info.context) else: rollbar.report_message( 'Error: Invalid role provided: ' + modified_user_data['role'], 'error', info.context) if success: util.invalidate_cache(project_name) util.invalidate_cache(query_args.get('email')) util.cloudwatch_log( info.context, 'Security: Modified user data:{user} \ in {project} project succesfully'.format( user=query_args.get('email'), project=project_name)) else: util.cloudwatch_log( info.context, 'Security: Attempted to modify user \ data:{user} in {project} project'.format( user=query_args.get('email'), project=project_name)) ret = \ EditUser(success=success, modified_user=User(project_name, modified_user_data['email'])) return ret
def convert_ndb_datetime_property(ndb_prop, registry=None): return Field(DateTime, description=ndb_prop._name)
class Query(object): payment = Field(PaymentType, payment_id=ID()) deduction = Field(DeductionType, deduction_id=ID()) registration = Field(RegistrationType, registration_id=ID()) registration_cart = Field(CartType, cart_id=ID(), parent_id=ID()) payments = List(PaymentType, parent_id=ID(), start_date=String(), end_date=String()) deductions = List(DeductionType, payment_id=ID()) registrations = List(RegistrationType, payment_id=ID()) unpaid_sessions = List(EnrollmentType) def resolve_payment(self, info, **kwargs): payment_id = kwargs.get('payment_id') if payment_id: return Payment.objects.get(id=payment_id) return None def resolve_deduction(self, info, **kwargs): deduction_id = kwargs.get('deduction_id') if deduction_id: return Deduction.objects.get(id=deduction_id) return None def resolve_registration(self, info, **kwargs): registration_id = kwargs.get('registration_id') if registration_id: return Registration.objects.get(id=registration_id) return None def resolve_registration_cart(self, info, **kwargs): cart_id = kwargs.get('cart_id') parent_id = kwargs.get('parent_id') if cart_id: return RegistrationCart.objects.get(id=cart_id) if parent_id: return RegistrationCart.objects.get(parent=parent_id) return None def resolve_payments(self, info, **kwargs): parent_id = kwargs.get('parent_id') start_date = kwargs.get('start_date') end_date = kwargs.get('end_date') if parent_id: if start_date and end_date: return Payment.objects.filter( created_at__gt=arrow.get(start_date).datetime, created_at__lt=arrow.get(end_date).datetime, parent=parent_id ) return Payment.objects.filter(parent=parent_id) if start_date and end_date: return Payment.objects.filter( created_at__gt=datetime.date(start_date), created_at__lt=datetime.date(end_date) ) return Payment.objects.all() def resolve_deductions(self, info, **kwargs): payment_id = kwargs.get('payment_id') if payment_id: return Deduction.objects.filter(payament=payment_id) return Deduction.objects.all() def resolve_registrations(self, info, **kwargs): payment_id = kwargs.get('payment_id') if payment_id: return Registration.objects.filter(payament=payment_id) return Registration.objects.all() def resolve_unpaid_sessions(self, info, **kwargs): enrollments = Enrollment.objects.all() final_enrollments = [] for enrollment in enrollments: if enrollment.course.course_type == Course.CLASS and enrollment.sessions_left < 0: final_enrollments.append(enrollment) elif enrollment.sessions_left <= 0: final_enrollments.append(enrollment) return final_enrollments
lambda k, v: R.prop_or(lambda typ: typ(), 'type_modifier', v) (R.prop('type', v)), geometry_data_fields)) node_data_fields = dict( name=dict(type=String), # Index is the number used by the links to identify the node in a set of nodes node_index=dict(type=Int), type=dict(type=String), value=dict(type=Float), # TODO this should be a rescape_region FeatureCollection type to hold full geojson geometry=dict( type=GeometryDataType, graphene_type=GeometryDataType, fields=geometry_data_fields, type_modifier=lambda typ: Field(typ, resolver=resolver_for_dict_field), ), properties=dict(type=String, type_modifier=lambda typ: List(typ)), propertyValues=dict(type=String, type_modifier=lambda typ: List(typ)), coordinates=dict(type=Float), isGeneralized=dict(type=Boolean), ) NodeDataType = type( 'NodeDataType', (ObjectType, ), R.map_with_obj( # If we have a type_modifier function, pass the type to it, otherwise simply construct the type lambda k, v: R.prop_or(lambda typ: typ(), 'type_modifier', v) (R.prop('type', v)), node_data_fields))