class GuideApiRelationships(Relationships): items = fields.Nested( DataRelationship, many=False, _type='item', path='items', show_data=True, required=True, default=[], # url_template='{object_url}/guides', )
class LaboratoryApiAttrs(ObjectAttrs): title = TranslatedStr() notes = TranslatedStr() event_type = fields.String() execution_date = fields.Date() reports = fields.Nested(ReportSchema, many=True) class Meta: object_type = 'Laboratory' url_template = '{api_url}/laboratories/{ident}' model = 'laboratory.LabEvent'
def __init__( self, only=None, exclude=(), many=False, context=None, load_only=(), dump_only=(), partial=False, unknown=None, ): data_cls = type('{}Data'.format(self.__class__.__name__), (Object, ), {}) setattr(data_cls.opts, 'attrs_schema', self.opts.attrs_schema) self._declared_fields['data'] = fields.Nested(data_cls, name='data', many=many) if self.opts.meta_schema: if self.opts.aggs_schema: self.opts.meta_schema._declared_fields[ 'aggregations'] = fields.Nested(self.opts.aggs_schema, many=False) self._declared_fields['meta'] = fields.Nested( self.opts.meta_schema, name='meta', many=False) if self.opts.links_schema: self._declared_fields['links'] = fields.Nested( self.opts.links_schema, name='links', many=False) context = context or {} context['is_listing'] = many super().__init__(only=only, exclude=exclude, many=False, context=context, load_only=load_only, dump_only=dump_only, partial=partial, unknown=unknown)
def __init__( self, only=None, exclude=(), many=False, context=None, load_only=(), dump_only=(), partial=False, unknown=None, ): super().__init__(only=only, exclude=exclude, many=many, context=context, load_only=load_only, dump_only=dump_only, partial=partial, unknown=unknown) _meta = getattr(self, 'Meta', None) rel_cls = getattr(_meta, 'relationships_cls', DummyRelationship) self.fields['attributes'] = fields.Nested( getattr(_meta, 'attrs_cls', DummyAttributes), name='attributes') if 'relationships' not in self.fields: self.fields['relationships'] = fields.Nested(rel_cls, name='relationships') _type = getattr(_meta, '_type', None) if _type: self.fields['_type'] = fields.Str(required=True, missing=_type, default=_type, data_key='type')
class ResourceApiRelationships(Relationships): dataset = fields.Nested(Relationship, many=False, _type='dataset', path='datasets', url_template='{api_url}/datasets/{ident}') institution = fields.Nested(Relationship, many=False, _type='institution', attribute="institution", url_template='{api_url}/institutions/{ident}') subscription = fields.Nested( Relationship, many=False, _type='subscription', url_template='{api_url}/auth/subscriptions/{ident}') tabular_data = fields.Nested( Relationship, many=False, _type='tabular_data', url_template='{api_url}/resources/{ident}/data') geo_data = fields.Nested(Relationship, many=False, _type='geo_data', url_template='{api_url}/resources/{ident}/geo') chart = fields.Nested(Relationship, many=False, _type='chart', attribute="chartable", url_template='{api_url}/resources/{ident}/chart')
class ApplicationApiRelationships(Relationships): datasets = fields.Nested( Relationship, many=False, _type='dataset', url_template='{object_url}/datasets', ) @pre_dump def prepare_data(self, data): if not self.context.get('is_listing', False): data['datasets'] = data['datasets'].filter(status='published') return data
class AgentApiRelationships(UserApiRelationships): planned_schedule = fields.Nested( Relationship, many=False, _type='schedule', url_template='{api_url}/auth/schedules/{ident}', ) planned_user_schedule = fields.Nested( Relationship, many=False, _type='user_schedule', attribute='_planned_user_schedule', url_template='{object_url}', ) planned_user_schedule_items = fields.Nested( DataRelationship, many=False, default=[], _type='user_schedule_item', show_data=True, url_template='{object_url}', ) class Meta: ordered = True def prepare_object_url(self, data): obj = data.get('_planned_user_schedule') if obj: url = f'{self.api_url}/auth/user_schedules/{obj.id}' self._fields['planned_user_schedule'].schema.context.update( object_url=url) self._fields['planned_user_schedule_items'].schema.context.update( object_url=f'{url}/items') else: self._fields['planned_user_schedule'].schema.context.update( object_url='') self._fields['planned_user_schedule_items'].schema.context.update( object_url='')
class ArticleApiAggs(ExtSchema): by_created = fields.Nested( Aggregation, many=True, attribute='_filter_by_created.by_created.buckets', ) by_modified = fields.Nested( Aggregation, many=True, attribute='_filter_by_modified.by_modified.buckets', ) by_category = fields.Nested( CategoryAggregation, many=True, attribute='_filter_by_category.by_category.inner.buckets') by_tag = fields.Nested(Aggregation, many=True, attribute='_filter_by_tag.by_tag.inner.buckets') by_keyword = fields.Nested( Aggregation, many=True, attribute='_filter_by_keyword.by_keyword.inner.inner.buckets')
class ResourceCSVMetadataSerializer(schemas.ExtSchema): frontend_absolute_url = fields.Url(data_key=_('Resource URL')) title = TranslatedStr(data_key=_('Resource title'), default='') description = TranslatedStr(data_key=_('Resource description')) created = fields.DateTime(data_key=_('Resource created'), format='iso8601') data_date = fields.Date(data_key=_('Data date')) openness_score = fields.Int(data_key=_('Openness score')) resource_type = fields.Function(lambda obj: obj.get_type_display(), data_key=_('Type')) format = fields.Str(data_key=_('File format'), default='') file_size = fields.Function(lambda obj: sizeof_fmt(obj.file_size) if obj.file_size else '', data_key=_('File size')) views_count = fields.Int(attribute='computed_views_count', data_key=_("Resource views count")) downloads_count = fields.Int(attribute='computed_downloads_count', data_key=_("Resource downloads count")) has_table = fields.Function(lambda obj: _('YES') if obj.has_table else _('NO'), data_key=_('Table')) has_chart = fields.Function(lambda obj: _('YES') if obj.has_chart else _('NO'), data_key=_('Map')) has_map = fields.Function(lambda obj: _('YES') if obj.has_map else _('NO'), data_key=_('Chart')) download_url = fields.Url(data_key=_('Download URL')) data_special_signs = fields.Nested(SpecialSignSchema, data_key=_('special signs'), many=True) @ma.post_dump(pass_many=False) def prepare_nested_data(self, data, **kwargs): special_signs = data.get(_('special signs')) signs_str = '\n'.join([ '{name_label}: {name}, {symbol_label}: "{symbol}", {desc_label}: {desc}' .format(name=sign['name'], name_label=_('name'), symbol=sign['symbol'], symbol_label=_('symbol'), desc=sign['description'], desc_label=_('description')) for sign in special_signs ]) data[_('special signs')] = signs_str values_with_html = [_('Resource title'), _('Resource description')] for attribute in values_with_html: data[attribute] = strip_tags(data[attribute]) return data class Meta: ordered = True
def __init__( self, only=None, exclude=(), many=False, context=None, load_only=(), dump_only=(), partial=False, unknown=None, ): self._declared_fields['attributes'] = fields.Nested( self.opts.attrs_schema, name='attributes', many=False) relationships_schema = getattr(self.opts.attrs_schema.opts, 'relationships_schema', None) if relationships_schema: self._declared_fields['relationships'] = fields.Nested( relationships_schema, many=False, name='relationships') meta_schema = getattr(self.opts.attrs_schema.opts, 'meta_schema', None) if meta_schema: self._declared_fields['meta'] = fields.Nested(meta_schema, many=False, name='meta') super().__init__(only=only, exclude=exclude, many=many, context=context, load_only=load_only, dump_only=dump_only, partial=partial, unknown=unknown)
class SubscriptionRelationship(ExtSchema): data = fields.Nested(RelationshipData) links = fields.Nested(RelationshipLinks, required=True, many=False) meta = fields.Nested(RelationshipMeta, many=False) @pre_dump def prepare_data(self, data, **kwargs): if data.watcher_type == 'model': obj_name = MODEL_TO_OBJECT_NAME[data.object_name] related = data.obj.get_api_url(base_url=self.api_url) if hasattr( self, 'api_url') else data.obj.api_url else: obj_name = 'query' related = data.object_ident obj_name = obj_name.lower() return { 'data': { 'id': str(data.object_ident), '_type': obj_name }, 'links': { 'related': related }, }
def __init__( self, only=None, exclude=(), many=False, context=None, load_only=(), dump_only=(), partial=False, unknown=None, ): data_cls = type( '{}Data'.format(self.__class__.__name__), (self.opts.object_schema,), {} ) setattr(data_cls.opts, 'attrs_schema', self.opts.attrs_schema) self._declared_fields['data'] = fields.Nested(data_cls, name='data', many=False) super().__init__(only=only, exclude=exclude, many=False, context=context, load_only=load_only, dump_only=dump_only, partial=partial, unknown=unknown)
class CreateSubmissionAttrs(ObjectAttrs): applicant_email = core_fields.Email(required=False, default=None) author = core_fields.Str(required=False, default=None) title = core_fields.Str(required=True, faker_type='application title', example='Some App') url = core_fields.Url(required=True) notes = core_fields.Str(required=True) image = core_fields.Base64String(required=False, default=None, max_size=settings.IMAGE_UPLOAD_MAX_SIZE) illustrative_graphics = core_fields.Base64String( required=False, default=None, max_size=settings.IMAGE_UPLOAD_MAX_SIZE) image_alt = core_fields.Str(required=False, default=None) datasets = core_fields.List(core_fields.Str(), required=False, default=[]) external_datasets = core_fields.Nested(ExternalResourceSchema, required=False, default={}, many=True) keywords = core_fields.List(core_fields.Str(), default='', required=False) comment = core_fields.String(required=False, description='Comment body', example='Looks unpretty', default='') is_personal_data_processing_accepted = core_fields.Boolean(required=True) is_terms_of_service_accepted = core_fields.Boolean(required=True) class Meta: strict = True ordered = True object_type = 'application-submission' @pre_load def prepare_data(self, data, **kwargs): data['datasets'] = [ x.replace('dataset-', '') for x in data.get('datasets', []) if x ] return data @validates('is_personal_data_processing_accepted') def validate_is_personal_data_processing_accepted(self, value): if not value: raise ValidationError(_('This field is required')) @validates('is_terms_of_service_accepted') def validate_is_terms_of_service_accepted(self, value): if not value: raise ValidationError(_('This field is required'))
class DataRelationship(Relationship): data = fields.Nested(RelationshipData, many=True) @pre_dump def prepare_data(self, data, **kwargs): res = super().prepare_data(data, **kwargs) show_data = self.context.get('show_data', False) if show_data: _type = self.context['_type'] for item in data: if isinstance(item, dict): item.update({'_type': _type}) else: setattr(item, '_type', _type) res['data'] = data return res
def __init__( self, only=None, exclude=(), many=False, context=None, load_only=(), dump_only=(), partial=False, unknown=None, ): super().__init__(only=only, exclude=exclude, many=many, context=context, load_only=load_only, dump_only=dump_only, partial=partial, unknown=unknown) many = self.context.get('many', False) if many: self.fields['count'] = fields.Int(required=True, missing=0, default=0) _meta = getattr(self, 'Meta', None) aggs_cls = getattr(_meta, 'aggregations_cls', None) self.fields['aggregations'] = fields.Nested(aggs_cls, name='aggregations', required=False) if aggs_cls else fields.Dict(nullable=True)
class SubscriptionQuerySchema(Object): links = fields.Nested(SubscriptionQueryLinks, required=True, many=False) class Meta: attrs_schema = SubscriptionQueryAttrs @pre_dump def prepare_data(self, data, **kwargs): return { 'attributes': { 'title': data.name, }, 'id': str(data.watcher.object_ident), '_type': 'query', 'links': { 'related': data.watcher.object_ident }, }
class SubmissionAttrs(ObjectAttrs): title = fields.Str(required=True, example='Very important data') notes = fields.Str(required=True, example='We need this data to save the world') organization_name = fields.Str(required=False, example='ACME') data_link = fields.Url(required=False, example='https://duckduckgo.com') potential_possibilities = fields.Str(required=False) submission_date = fields.Date(required=True) decision_date = fields.Date(required=True) published_at = fields.DateTime(required=True) feedback_counters = fields.Nested( FeedbackCounters, many=False ) my_feedback = fields.Str(required=False) class Meta: object_type = 'submission' path = 'submissions' url_template = '{api_url}/submissions/accepted/{ident}'
class ResourceXMLSerializer(schemas.ExtSchema): id = fields.Integer() access_url = fields.Url(attribute='frontend_absolute_url') title = TranslatedStr() description = TranslatedStr() openness_score = fields.Integer() format = fields.Str() views_count = fields.Int(attribute='computed_views_count') downloads_count = fields.Int(attribute='computed_downloads_count') created = fields.DateTime(format='iso8601') data_date = fields.Date() type = fields.Function(lambda resource: resource.get_type_display()) file_size = fields.Function(lambda obj: sizeof_fmt(obj.file_size) if obj.file_size else '') visualization_types = ListWithoutNoneStrElement(fields.Str()) download_url = fields.Str() data_special_signs = fields.Nested(SpecialSignSchema, data_key='special_signs', many=True)
def __init__( self, only=None, exclude=(), many=False, context=None, load_only=(), dump_only=(), partial=False, unknown=None, ): super().__init__(only=only, exclude=exclude, many=many, context=context, load_only=load_only, dump_only=dump_only, partial=partial, unknown=unknown) _meta = getattr(self, 'Meta', None) if not issubclass(self._data_cls, REQData): raise Exception("{} must be a subclass of ResponseData".format(self._data_cls.__class__)) setattr(self._data_cls.Meta, 'attrs_cls', getattr(_meta, 'attrs_cls', DummyAttributes)) setattr(self._data_cls.Meta, 'relationship_cls', getattr(_meta, 'relationship_cls', DummyRelationship)) setattr(self._data_cls.Meta, '_type', getattr(_meta, '_type', None)) self.fields['data'] = fields.Nested(self._data_cls, name='data', many=self.many, data_key='data')
class CourseApiAttrs(ObjectAttrs, HighlightObjectMixin): title = fields.Str() notes = fields.Str() participants_number = fields.Int() venue = fields.Str() start = fields.Date() end = fields.Date() file_type = fields.Str() file_url = fields.URL() materials_file_type = fields.Str() materials_file_url = fields.URL() sessions = fields.Nested(CourseModuleSchema, many=True) state = fields.Str() state_name = fields.Str() class Meta: # relationships_schema = ApplicationApiRelationships object_type = 'course' url_template = '{api_url}/courses/{ident}' model = 'academy.Course' @pre_dump def prepare_data(self, data, **kwargs): if data.start and data.end: today = timezone.now().date() start_date = data.start.date() end_date = data.end.date() _state = None if start_date <= today <= end_date: _state = 'current' elif end_date < today: _state = 'finished' elif today < start_date: _state = 'planned' if _state: setattr(data, 'state', _state) setattr(data, 'state_name', Course.COURSE_STATES.get(_state)) return data
class SubscriptionResponse(jss.ResponseSchema): included = fields.Nested(SubscriptionIncludes, many=True) class Meta: data_cls = SubscriptionObject meta_cls = jss.ResponseMeta @pre_dump(pass_many=True) def prepare_included(self, request, many): included = {} subscriptions = request.data if many else [ request.data, ] for subscription in subscriptions: subscribed_object = subscription.watcher.obj.serialized if subscribed_object: key = '{}-{}'.format(subscribed_object['type'], subscribed_object['id']) included.setdefault(key, subscribed_object) if included: request.included = included.values() return request
class InstitutionApiAttrs(ObjectAttrs, HighlightObjectMixin): abbreviation = fields.Str() city = fields.Str() created = fields.Str() datasets_count = fields.Int(attribute='published_datasets_count') email = fields.Str() epuap = fields.Str() fax = fields.Str() flat_number = fields.Str() followed = fields.Boolean() image_url = fields.Str() institution_type = fields.Str() modified = fields.Str() description = TranslatedStr() postal_code = fields.Str() regon = fields.Str() resources_count = fields.Int(attribute='published_resources_count') slug = TranslatedStr() sources = fields.Nested(DataSourceAttr, many=True) street = fields.Str() street_number = fields.Str() street_type = fields.Str() tel = fields.Str() title = TranslatedStr() website = fields.Str() class Meta: relationships_schema = InstitutionApiRelationships object_type = 'institution' url_template = '{api_url}/institutions/{ident}' model = 'organizations.Organization' @post_dump(pass_many=False) def prepare_notes(self, data, **kwargs): data["notes"] = data.get("description") return data
def __init__(self, meta, **kwargs): SchemaOpts.__init__(self, meta, **kwargs) self.attrs_schema = getattr(meta, 'attrs_schema', None) self.aggs_schema = getattr(meta, 'aggs_schema', None) self.data_schema = getattr(meta, 'data_schema', None) # self.errors_schema = getattr(meta, 'errors_schema', ResponseErrors) self.meta_schema = getattr(meta, 'meta_schema', TopLevelMeta) self.links_schema = getattr(meta, 'links_schema', TopLevelLinks) self.max_items_num = getattr(meta, 'max_items_num', 10000) if self.attrs_schema and not issubclass(self.attrs_schema, ObjectAttrs): raise Exception("{} must be a subclass of ObjectAttrs".format(self.attrs_schema)) if self.data_schema and not issubclass(self.data_schema, schemas.ExtSchema): raise Exception("{} must be a subclass of {}".format(self.data_schema, schemas.ExtSchema.__name__)) if self.meta_schema and not issubclass(self.meta_schema, TopLevelMeta): raise Exception("{} must be a subclass of Meta".format(self.meta_schema)) if self.aggs_schema: if not issubclass(self.aggs_schema, schemas.ExtSchema): raise Exception("{} must be a subclass of ExtSchema".format(self.aggs_schema)) self.meta_schema.aggregations = fields.Nested(self.aggs_schema, many=False) if self.links_schema and not issubclass(self.links_schema, TopLevelLinks): raise Exception("{} must be a subclass of Links".format(self.links_schema))
class DatasetApiAggregations(ExtSchema): by_format = fields.Nested(Aggregation, many=True, attribute='_filter_by_format.by_format.buckets') by_institution = fields.Nested( DatasetsByInstitutionAgg, many=True, attribute='_filter_by_institution.by_institution.inner.buckets') by_type = fields.Nested(Aggregation, many=True, attribute='_filter_by_type.by_type.buckets') by_category = fields.Nested( DatasetByCategoryAgg, many=True, attribute='_filter_by_category.by_category.inner.buckets') by_openness_score = fields.Nested( Aggregation, many=True, attribute='_filter_by_openness_score.by_openness_score.buckets') by_tag = fields.Nested(Aggregation, many=True, attribute='_filter_by_tag.by_tag.buckets')
class ExtLinksSchema(schemas.ExtSchema): href = fields.String(required=True) meta = fields.Nested(ExtLinksMeta, name='meta')
class ApplicationApiAggs(ExtSchema): by_modified = fields.Nested( Aggregation, many=True, attribute='_filter_by_format.by_modified.buckets')
class DummyRelationship(schemas.ExtSchema): dummy = fields.Nested(Relationship, name='dummy') class Meta: nullable = True
class Object(schemas.ExtSchema): OPTIONS_CLASS = ObjectOpts id = fields.Str(required=True) links = fields.Nested(ObjectLinks, name='links') _type = fields.String(required=True, data_key='type') def __init__( self, only=None, exclude=(), many=False, context=None, load_only=(), dump_only=(), partial=False, unknown=None, ): self._declared_fields['attributes'] = fields.Nested( self.opts.attrs_schema, name='attributes', many=False ) relationships_schema = getattr(self.opts.attrs_schema.opts, 'relationships_schema', None) if relationships_schema: self._declared_fields['relationships'] = fields.Nested(relationships_schema, many=False, name='relationships') meta_schema = getattr(self.opts.attrs_schema.opts, 'meta_schema', None) if meta_schema: self._declared_fields['meta'] = fields.Nested(meta_schema, many=False, name='meta') super().__init__(only=only, exclude=exclude, many=many, context=context, load_only=load_only, dump_only=dump_only, partial=partial, unknown=unknown) @pre_dump(pass_many=False) def prepare_data(self, data, **kwargs): id = getattr(data, 'id', None) or getattr(data.meta, 'id') slug = getattr(data, 'slug', None) if isinstance(slug, AttrDict): lang = get_language() slug = slug[lang] ident = '{},{}'.format(id, slug) if slug else str(id) res = dict( attributes=data, id=str(id), _type=self.opts.attrs_schema.opts.object_type ) if hasattr(self.opts.attrs_schema, 'self_api_url'): object_url = self.opts.attrs_schema.self_api_url(data) else: object_url = self.opts.attrs_schema.opts.url_template.format( api_url=self.api_url, ident=ident, data=data ) if object_url: res['links'] = { 'self': object_url } if 'meta' in self._declared_fields: res['meta'] = data if 'relationships' in self.fields: relationships = {} for name, field in self.fields['relationships'].schema.fields.items(): _name = field.attribute or name field.schema.context.update(object_url=object_url) value = getattr(data, _name, None) if isinstance(value, Manager): value = value.values() if value or field.required: relationships[_name] = value relationships['object_url'] = object_url if relationships: res['relationships'] = relationships return res
class RelationshipLinks(schemas.ExtSchema): related = fields.Nested(ExtLinksSchema, name='related') class Meta: nullable = True
class CommentApiRelationships(Relationships): dataset = fields.Nested(Relationship, many=False, _type='dataset', url_template='{api_url}/datasets/{ident}')