class ActivatedApplicationSchema(ma.Schema): id = fields.String(dump_only=True) application = fields.Relationship( related_url='/applications/{application_id}', related_url_kwargs={'application_id': '<id>'}, many=True, schema=ApplicationSchema, include_resource_linkage=True, type_='applications', dump_only=True ) owner = fields.Relationship( related_url='/users/{user_id}', related_url_kwargs={'user_id': '<id>'}, many=False, schema=UserSchema, include_resource_linkage=True, type_='users', dump_only=True ) activate_date = fields.DateTime(dump_only=True) class Meta: type_ = 'activated-applications' strict = True inflect = common.dasherize
class PersonSchema(Schema): class Meta: type_ = 'person' self_view = 'person_detail' self_view_kwargs = {'id': '<id>'} self_view_many = 'person_list' id = fields.Integer(as_string=True, dump_only=True) name = fields.String(required=True) email = fields.Email(load_only=True) display_name = fields.Function( lambda obj: "{} <{}>".format(obj.name.upper(), obj.email)) computers = Relationship( self_view='person_computers', self_view_kwargs={'id': '<id>'}, related_view='computer_list', related_view_kwargs={'id': '<id>'}, many=True, schema='ComputerSchema', type_='computer', ) @pre_load def remove_id_before_deserializing(self, data, **kwargs): """ We don't want to allow editing ID on POST / PATCH Related issues: https://github.com/AdCombo/flask-combo-jsonapi/issues/34 https://github.com/miLibris/flask-rest-jsonapi/issues/193 """ if 'id' in data: del data['id'] return data
class BundleDependencySchema(PlainSchema): """ Plain (non-JSONAPI) Marshmallow schema for a single bundle dependency. Not defining this as a separate resource with Relationships because we only create a set of dependencies once at bundle creation. """ child_uuid = fields.String(validate=validate_uuid, dump_only=True) child_path = fields.String() # Validated in Bundle ORMObject parent_uuid = fields.String(validate=validate_uuid) parent_path = fields.String(missing="") parent_name = fields.Method('get_parent_name', dump_only=True) # for convenience def get_parent_name(self, dep): uuid = dep['parent_uuid'] return local.model.get_bundle_names([uuid]).get(uuid)
class PostSchema(Schema): class Meta: type_ = 'posts' self_view = 'post_detail' self_view_kwargs = {'id': '<id>'} self_view_many = 'post_list' id = fields.Integer(dump_only=True) created_at = fields.DateTime(dump_only=True) updated_at = fields.DateTime(dump_only=True) link = fields.Url() text = fields.String(required=True) rating = fields.Integer(dump_only=True) user = Relationship(attribute='user', self_view='post_user', self_view_kwargs={'id': '<id>'}, related_view='post_detail', related_view_kwargs={'id': '<id>'}, schema='UserSchema', type_='users') channel = Relationship(attribute='channel', self_view='post_channel', self_view_kwargs={'id': '<id>'}, related_view='post_detail', related_view_kwargs={'id': '<id>'}, schema='ChannelSchema', type_='channels') comments = Relationship(self_view='post_comments', self_view_kwargs={'id': '<id>'}, related_view='comment_list', related_view_kwargs={'id': '<id>'}, many=True, schema='CommentSchema', type_='comments')
class BundlePermissionSchema(Schema): id = CompatibleInteger(as_string=True, dump_only=True) bundle = fields.Relationship( include_resource_linkage=True, attribute='object_uuid', type_='bundles', load_only=True, required=True, ) group = fields.Relationship(include_resource_linkage=True, attribute='group_uuid', type_='groups', required=True) group_name = fields.String(dump_only=True) # for convenience permission = fields.Integer(validate=lambda p: 0 <= p <= 2) permission_spec = PermissionSpec(attribute='permission') # for convenience @validates_schema def check_permission_exists(self, data): if 'permission' not in data: raise ValidationError( "One of either permission or permission_spec must be provided." ) class Meta: type_ = 'bundle-permissions'
class RouteInputSchema(JSONAPISchema): id = fields.UUID() origin = fields.Nested(GeoJSONSchema, required=True) origin_name = fields.String(required=True) destination = fields.Nested(GeoJSONSchema, required=True) destination_name = fields.String(required=True) waypoints = fields.List(fields.Float) waypoints_names = fields.List(fields.String) polyline = fields.Nested(GeoJSONSchema, required=True) bounds = fields.Dict() created = fields.DateTime(allow_none=True) class Meta: type_ = 'routes' strict = True inflect = dasherize
class Delivery(Schema): id = fields.String(dump_only=True, attribute='placement_id') date = fields.DateTime() impressions = fields.Int() class Meta: type_ = 'delivery'
class HelloWorldSchema(Schema): id = fields.Str(dump_only=True) hello = fields.String() version = fields.Integer() class Meta: type_ = 'hello_world'
class EventSchema(Schema): id = fields.Integer(dump_only=True) instatid = fields.Integer() match_instatid = fields.Integer() player_instatid = fields.Integer() player_id = fields.Integer() player_name = fields.String() team_instatid = fields.Integer() team_id = fields.Integer() # match_id = fields.Integer() order_i = fields.Integer() end = fields.Decimal() half = fields.Integer() pos_x = fields.Decimal() pos_y = fields.Decimal() type = fields.Integer() creation_time = fields.DateTime(dump_only=True) # self links def get_top_level_links(self, data, many): if many: self_link = "/data/" else: self_link = "/data/{}".format(data['id']) return {'self': self_link} class Meta: type_ = 'data'
class AuthSchema(Schema): id = fields.String(dump_only=True) identity = fields.Nested(IdentitySchema) class Meta: type_ = 'auth' strict = True
class AuthenticatedUserSchema(UserSchema): email = fields.String() time_quota = fields.Integer() time_used = fields.Integer() disk_quota = fields.Integer() disk_used = fields.Integer() last_login = fields.LocalDateTime("%c")
class PasswordAuthSchema(Schema): id = fields.String(dump_only=True) user = fields.Nested(UserAuthSchema) class Meta: type_ = 'password' strict = True
class ProfileSchema(Schema): class Meta: type_ = 'profiles' self_view = 'profiles_api.profile_detail' self_view_kwargs = {'profile_id': '<id>'} self_view_many = 'profiles_api.profiles_list' id = fields.Int(dump_only=True) data = fields.String() description = fields.Str() display_name = fields.Str() expiration_date = fields.DateTime() identifier = fields.Str() organization = fields.Str() uuid = fields.UUID() removal_disallowed = fields.Boolean() version = fields.Int() scope = fields.Str() removal_date = fields.DateTime() duration_until_removal = fields.Int() consent_en = fields.Str() tags = Relationship(related_view='api_app.tag_detail', related_view_kwargs={'tag_id': '<id>'}, many=True, schema='TagSchema', type_='tags')
class AdminStatisticsMailSchema(Schema): """ Api schema """ class Meta: """ Meta class """ type_ = 'admin-statistics-mail' self_view = 'v1.admin_statistics_mail_detail' inflect = dasherize id = fields.String() one_day = fields.Method("mail_last_1_day") three_days = fields.Method("mail_last_3_days") seven_days = fields.Method("mail_last_7_days") thirty_days = fields.Method("mail_last_30_days") def mail_last_1_day(self, obj): return get_count(Mail.query.filter(datetime.now(pytz.utc) - Mail.time <= timedelta(days=1))) def mail_last_3_days(self, obj): return get_count(Mail.query.filter(datetime.now(pytz.utc) - Mail.time <= timedelta(days=3))) def mail_last_7_days(self, obj): return get_count(Mail.query.filter(datetime.now(pytz.utc) - Mail.time <= timedelta(days=7))) def mail_last_30_days(self, obj): return get_count(Mail.query.filter(datetime.now(pytz.utc) - Mail.time <= timedelta(days=30)))
class FilterObjectSchema(BaseSchema): """ A single filter object, e.g. { 'type': 'daterange', 'value': [], 'cmp': 'in' } """ type = f.String(validate=validate.OneOf( ["date", "daterange", "timedelta", "reportmeta", "samplemeta"])) value = f.Raw() key = f.Raw() cmp = f.String(validate=validate.OneOf( ["eq", "ne", "le", "lt", "ge", "gt", "in", "not in"]))
class PanelPermissionSchema(Schema): """ API Schema for panel permission Model """ class Meta: """ Meta class for user email API schema """ type_ = 'panel-permission' self_view = 'v1.panel_permission_detail' self_view_kwargs = {'id': '<id>'} inflect = dasherize id = fields.Str(dump_only=True) panel_name = fields.String(allow_none=False) can_access = fields.Boolean() custom_system_roles = Relationship( attribute='custom_system_roles', many=True, self_view='v1.panel_permissions_custom_system_roles', self_view_kwargs={'id': '<id>'}, related_view='v1.custom_system_role_list', related_view_kwargs={'panel_id': '<id>'}, schema='CustomSystemRoleSchema', type_='custom-system-role', )
class WorksheetBlockSchema(PlainSchema): id = fields.Integer() mode = fields.String(validate=validate.OneOf(set(BlockModes.values))) is_refined = fields.Bool() class Meta: type_ = 'worksheet-block'
class TableBlockSchema(WorksheetBlockSchema): mode = fields.Constant(BlockModes.table_block) bundles_spec = fields.Nested(BundlesSpecSchema, required=True) status = fields.Nested(FetchStatusSchema, required=True) header = fields.List(fields.String(), required=True) rows = fields.List(fields.Dict(), required=True)
class AdminStatisticsEventSchema(Schema): """ Api schema """ class Meta: """ Meta class """ type_ = 'admin-statistics-event' self_view = 'v1.admin_statistics_event_detail' inflect = dasherize id = fields.String() draft = fields.Method("events_draft_count") published = fields.Method("events_published_count") past = fields.Method("events_past_count") def events_draft_count(self, obj): return get_count(Event.query.filter_by(state='draft')) def events_published_count(self, obj): return get_count(Event.query.filter_by(state='published')) def events_past_count(self, obj): return get_count( Event.query.filter(Event.ends_at < datetime.now(pytz.utc)))
class RouteSchema(Schema): not_blank = validate.Length(min=1, error='Field cannot be blank') # add validate=not_blank in required fields id = fields.Integer(required=True) name = fields.String(required=True) length_in_meters = fields.Float(required=True) elevation_gain_in_meters = fields.Float(required=True) start_lat = fields.Float(required=True) start_lon = fields.Float(required=True) end_lat = fields.Float(required=True) end_lon = fields.Float(required=True) route_type = fields.Integer(required=True) sub_type = fields.Integer(required=True) popularity = fields.Float(required=True) # self links def get_top_level_links(self, data, many): if many: self_link = "/routes/" else: self_link = "/routes/{}".format(data['id']) return {'self': self_link} #The below type object is a resource identifier object as per http://jsonapi.org/format/#document-resource-identifier-objects class Meta: type_ = 'routes'
class PinSchema(Schema): id = fields.Str(dump_only=True) number = fields.Integer(required=True) name = fields.String(attribute='name') state = fields.Integer() sequences = fields.Relationship( related_url='/api/pins/{pin_id}/sequences', related_url_kwargs={'pin_id': '<id>'}, # Include resource linkage many=True, include_data=True, type_='sequences', schema='SequenceSchema' ) @post_load def make_pin(self, data): return Pin(**data) def handle_error(self, exc, data): raise ValidationError('An error occurred with input: {0} \n {1}'.format(data, exc.messages)) class Meta: type_ = 'pins' strict = True
class PrivateMessageSchema(Schema): id = fields.Integer() created_at = fields.DateTime() title = fields.String() type = fields.String(attribute="discriminator") class Meta: type_ = 'private_message' # Required participants = IncludingHyperlinkRelated(BaseUser, '/users/{user_id}', url_kwargs={'user_id': '<id>'}, many=True, include_data=True, type_='user' )
class AccountSchema(Schema): error = 'Enter a value between 4 and 32 characters long.' blank_user = validate.Length(min=4, max=32, error=error) error = 'Enter a value between 8 and 64 characters long.' blank_pass = validate.Length(min=8, max=64, error=error) id = fields.Integer(dump_only=True) roles = fields.String(dump_only=True) username = fields.String(validate=blank_user) password = fields.String(validate=blank_pass) messager_id = fields.Integer(dump_only=True) first_name = fields.String(dump_only=True) last_name = fields.String(dump_only=True) is_active = fields.Integer(dump_only=True)
class AdminStatisticsGroupSchema(Schema): """ Api schema """ class Meta: """ Meta class """ type_ = 'admin-statistics-group' self_view = 'v1.admin_statistics_group_detail' inflect = dasherize id = fields.String() groups = fields.Method("number_of_groups") group_events = fields.Method("number_of_group_events") followers = fields.Method("number_of_followers") def number_of_groups(self, obj): all_group = db.session.query(Group).all() return len(all_group) def number_of_group_events(self, obj): unique_group = Event.query.filter(Event.group_id.isnot(None)).all() return len(unique_group) def number_of_followers(self, obj): unique_follower = db.session.query(UserFollowGroup.user_id).distinct() return unique_follower.count()
class GroupSchema(Schema): id = fields.String(validate=validate_uuid, attribute='uuid') name = fields.String(required=True, validate=validate_name) user_defined = fields.Bool(dump_only=True) owner = fields.Relationship(include_resource_linkage=True, type_='users', attribute='owner_id') admins = fields.Relationship(include_resource_linkage=True, type_='users', many=True) members = fields.Relationship(include_resource_linkage=True, type_='users', many=True) class Meta: type_ = 'groups'
class SpeakersCallSchema(SoftDeletionSchema): """ Api Schema for Speakers Call model """ class Meta: """ Meta class for Speakers Call Api Schema """ type_ = 'speakers-call' self_view = 'v1.speakers_call_detail' self_view_kwargs = {'id': '<id>'} inflect = dasherize @validates_schema(pass_original=True) def validate_date(self, data, original_data): if 'id' in original_data['data']: speakers_calls = SpeakersCall.query.filter_by( id=original_data['data']['id']).one() if 'starts_at' not in data: data['starts_at'] = speakers_calls.starts_at if 'ends_at' not in data: data['ends_at'] = speakers_calls.ends_at # if 'event_starts_at' not in data: # data['event_starts_at'] = speakers_calls.event.starts_at if data['starts_at'] >= data['ends_at']: raise UnprocessableEntity( {'pointer': '/data/attributes/ends-at'}, "ends-at should be after starts-at", ) # if 'event_starts_at' in data and data['starts_at'] > data['event_starts_at']: # raise UnprocessableEntity({'pointer': '/data/attributes/starts-at'}, # "speakers-call starts-at should be before event starts-at") # if 'event_starts_at' in data and data['ends_at'] > data['event_starts_at']: # raise UnprocessableEntity({'pointer': '/data/attributes/ends-at'}, # "speakers-call ends-at should be before event starts-at") id = fields.Str(dump_only=True) announcement = fields.Str(required=True) starts_at = fields.DateTime(required=True) ends_at = fields.DateTime(required=True) hash = fields.Str(allow_none=True) privacy = fields.String( validate=validate.OneOf(choices=["private", "public"]), allow_none=True) event = Relationship( attribute='event', self_view='v1.speakers_call_event', self_view_kwargs={'id': '<id>'}, related_view='v1.event_detail', related_view_kwargs={'speakers_call_id': '<id>'}, schema='EventSchemaPublic', type_='event', )
class ComputerSchema(Schema): class Meta: type_ = 'computer' self_view = 'computer_detail' self_view_kwargs = {'id': '<id>'} id = fields.Integer(as_string=True, dump_only=True) serial = fields.String(required=True) owner = Relationship( attribute='person', self_view='computer_person', self_view_kwargs={'id': '<id>'}, related_view='person_detail', related_view_kwargs={'computer_id': '<id>'}, schema='PersonSchema', type_='person', ) @pre_load def remove_id_before_deserializing(self, data, **kwargs): """ We don't want to allow editing ID on POST / PATCH Related issues: https://github.com/AdCombo/flask-combo-jsonapi/issues/34 https://github.com/miLibris/flask-rest-jsonapi/issues/193 """ if 'id' in data: del data['id'] return data
class SampleSchema(Schema): class Meta: sqla_session = db.session model = models.Sample type_ = "samples" self_view = "rest_api.sample" self_view_many = "rest_api.samplelist" self_view_kwargs = {"id": "<id>"} id = f.Integer(attribute="sample_id", allow_none=True, as_string=True) name = f.String(attribute="sample_name") data = Relationship( related_view="rest_api.sample_sampledatalist", related_view_kwargs={"id": "<sample_id>"}, many=True, type_="sample_data", # include_resource_linkage=True, schema="SampleDataSchema", ) report = Relationship( related_view="rest_api.report", related_view_kwargs={"id": "<report_id>"}, many=False, type_="reports", id_field="report_id", include_resource_linkage=True, schema="ReportSchema", )
class ComputerSchema(Schema): class Meta: type_ = "computer" self_view = "computer_detail" self_view_kwargs = {"id": "<id>"} self_view_many = "computer_list" id = fields.Integer(as_string=True, dump_only=True) serial = fields.String(required=True) owner = Relationship( nested="PersonSchema", schema="PersonSchema", attribute="person", self_view="computer_detail", self_view_kwargs={"id": "<id>"}, related_view="person_detail", related_view_kwargs={"int": "<id>"}, type_="person", ) @pre_load def remove_id_before_deserializing(self, data, **kwargs): """ We don't want to allow editing ID on POST / PATCH Related issues: https://github.com/AdCombo/flask-combo-jsonapi/issues/34 https://github.com/miLibris/flask-rest-jsonapi/issues/193 """ if "id" in data: del data["id"] return data
class FilterObjectSchema(BaseSchema): """ A single filter object, e.g. { 'type': 'daterange', 'value': [], 'cmp': 'in' } """ type = f.String(validate=validate.OneOf( ['date', 'daterange', 'timedelta', 'reportmeta', 'samplemeta'])) value = f.Raw() key = f.Raw() cmp = f.String(validate=validate.OneOf( ['eq', 'ne', 'le', 'lt', 'ge', 'gt', 'in', 'not in']))