class DatasetApiAttrs(ObjectAttrs): title = TranslatedStr() slug = TranslatedStr() notes = TranslatedStr() category = fields.Nested(DatasetCategoryAttr, many=False) formats = fields.List(fields.String) tags = TranslatedTagsList(TranslatedStr(), attr='tags_list') openness_scores = fields.List(fields.Int()) license_condition_db_or_copyrighted = fields.String() license_condition_modification = fields.Boolean() license_condition_original = fields.Boolean() license_condition_responsibilities = fields.String() license_condition_source = fields.Boolean() license_condition_timestamp = fields.Boolean() license_name = fields.String() license_description = fields.String() update_frequency = TransUpdateFreqField() views_count = fields.Integer() url = fields.String() followed = fields.Boolean() modified = fields.DateTime() resource_modified = fields.DateTime() created = fields.DateTime() verified = fields.DateTime() class Meta: relationships_schema = DatasetApiRelationships object_type = 'dataset' url_template = '{api_url}/datasets/{ident}'
class UserSchemaMixin(object): state = fields.Str( required=True, faker_type='userstate', example='active', description="Allowed values: 'active', 'inactive' or 'blocked'") email = fields.Email(required=True, faker_type='email', example='*****@*****.**') fullname = fields.Str(missing=None, faker_type='name', example='Jan Kowalski') about = fields.Str(missing=None, faker_type='sentence', example='I am a very talented programmer.') created = fields.Date() subscriptions_report_opt_in = fields.Boolean() rodo_privacy_policy_opt_in = fields.Boolean() count_datasets_created = fields.Int() count_datasets_modified = fields.Int() @post_dump def prepare_data(self, data, **kwargs): data['subscriptions_report_opt_in'] = True if data.get( 'subscriptions_report_opt_in') is not None else False data['rodo_privacy_policy_opt_in'] = True if data.get( 'rodo_privacy_policy_opt_in') is not None else False return data
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 ApplicationApiAttrs(ObjectAttrs, HighlightObjectMixin): slug = TranslatedStr() title = TranslatedStr() notes = TranslatedStr() author = fields.Str(faker_type='firstname') url = fields.Str(faker_type='url') image_url = fields.Str(faker_type='image_url') image_thumb_url = fields.Str(faker_type='image_thumb_url') image_alt = TranslatedStr() illustrative_graphics_url = fields.Str() illustrative_graphics_alt = TranslatedStr() followed = fields.Boolean(faker_type='boolean') keywords = KeywordsList(TranslatedStr(), faker_type='tagslist') views_count = fields.Integer(faker_type='integer') modified = fields.Str(faker_type='datetime') created = fields.Str(faker_type='datetime') has_image_thumb = fields.Bool() main_page_position = fields.Int() external_datasets = fields.Nested(ExternalDataset, many=True) class Meta: relationships_schema = ApplicationApiRelationships object_type = 'application' url_template = '{api_url}/applications/{ident}' model = 'applications.Application'
class InstitutionApiAttrs(ObjectAttrs): slug = TranslatedStr() title = TranslatedStr() description = TranslatedStr() image_url = fields.Str() postal_code = fields.Str() city = fields.Str() street_type = fields.Str() street = fields.Str() street_number = fields.Str() flat_number = fields.Str() email = fields.Str() epuap = fields.Str() fax = fields.Str(attribute='fax_display') tel = fields.Str(attribute='phone_display') regon = fields.Str() website = fields.Str() institution_type = fields.Str() followed = fields.Boolean() modified = fields.Str() created = fields.Str() class Meta: relationships_schema = InstitutionApiRelationships object_type = 'institution' url_template = '{api_url}/institutions/{ident}'
class DatasetCSVSchema(CSVSerializer): id = fields.Integer(data_key=_('id'), required=True) uuid = fields.Str(data_key=_("uuid"), default='') title = fields.Str(data_key=_("title"), default='') notes = fields.Str(data_key=_("notes"), default='') url = fields.Str(data_key=_("url"), default='') update_frequency = fields.Str(data_key=_("Update frequency"), default='') institution = fields.Str(data_key=_("Institution"), attribute='organization.id', default='') category = fields.Str(data_key=_("Category"), default='') status = fields.Str(data_key=_("Status"), default='') is_licence_set = fields.Boolean(data_key=_("Conditions for re-use"), default=None) created_by = fields.Int(attribute='created_by.id', data_key=_("created_by"), default=None) created = fields.DateTime(data_key=_("created"), default=None) modified_by = fields.Int(attribute='modified_by.id', data_key=_("modified_by"), default=None) modified = fields.DateTime(data_key=_("modified"), default=None) followers_count = fields.Str(data_key=_("The number of followers"), default=None) class Meta: ordered = True model = 'datasets.Dataset'
class UpdateSubscriptionAttrs(core_schemas.ExtSchema): name = core_fields.String(description='Subscription name', example='my query 1', required=False) enable_notifications = core_fields.Boolean(description='Enable notifications', example=True, required=False) customfields = core_fields.Raw() class Meta: strict = True ordered = True
class ResourceApiAttrs(ObjectAttrs, HighlightObjectMixin): title = TranslatedStr() description = TranslatedStr() category = fields.Str() format = fields.Str() media_type = fields.Str( attribute='type' ) # https://jsonapi.org/format/#document-resource-object-fields visualization_types = ListWithoutNoneStrElement(fields.Str()) downloads_count =\ fields.Function( lambda obj: obj.computed_downloads_count if is_enabled('S16_new_date_counters.be') else obj.downloads_count) openness_score = fields.Integer() views_count =\ fields.Function( lambda obj: obj.computed_views_count if is_enabled('S16_new_date_counters.be') else obj.views_count) modified = fields.DateTime() created = fields.DateTime() verified = fields.DateTime() data_date = fields.Date() file_url = fields.Str() file_size = fields.Integer() csv_file_url = fields.Str() csv_file_size = fields.Integer() jsonld_file_url = fields.Str() jsonld_file_size = fields.Integer() jsonld_download_url = fields.Str() download_url = fields.Str() csv_download_url = fields.Str() link = fields.Str() data_special_signs = fields.Nested(SpecialSignSchema, data_key='special_signs', many=True) is_chart_creation_blocked = fields.Bool() if is_enabled('S35_high_value_data.be'): has_high_value_data = fields.Boolean() if is_enabled('S37_resources_admin_region_data.be'): regions = fields.Method('get_regions') if is_enabled('S40_new_file_model.be'): files = fields.Method('get_files') class Meta: relationships_schema = ResourceApiRelationships object_type = 'resource' api_path = 'resources' url_template = '{api_url}/resources/{ident}' model = 'resources.Resource' def get_regions(self, res): return RegionSchema(many=True).dump( getattr(res, 'all_regions', res.regions)) def get_files(self, res): return ResourceFileSchema(many=True).dump( getattr(res, 'all_files', res.files))
class ShowcaseApiAttrs(ObjectAttrs, HighlightObjectMixin): category = fields.Str() category_name = fields.Method('get_category_name') slug = TranslatedStr() title = TranslatedStr() notes = TranslatedStr() author = fields.Str(faker_type='firstname') url = fields.Str(faker_type='url') image_url = fields.Str(faker_type='image_url') image_thumb_url = fields.Str(faker_type='image_thumb_url') image_alt = TranslatedStr() illustrative_graphics_url = fields.Str() illustrative_graphics_alt = TranslatedStr() followed = fields.Boolean(faker_type='boolean') keywords = KeywordsList(TranslatedStr(), faker_type='tagslist') views_count = fields.Integer(faker_type='integer') modified = fields.Str(faker_type='datetime') created = fields.Str(faker_type='datetime') has_image_thumb = fields.Bool() main_page_position = fields.Int() external_datasets = fields.Nested(ExternalDataset, many=True) # application showcase fields: is_mobile_app = fields.Bool() is_mobile_app_name = fields.Method('get_is_mobile_app_name') is_desktop_app = fields.Bool() is_desktop_app_name = fields.Method('get_is_desktop_app_name') mobile_apple_url = fields.URL() mobile_google_url = fields.URL() desktop_linux_url = fields.URL() desktop_macos_url = fields.URL() desktop_windows_url = fields.URL() license_type = fields.Str() license_type_name = fields.Method('get_license_type_name') # api use showcase fields: file_url = fields.Str() class Meta: relationships_schema = ShowcaseApiRelationships object_type = 'showcase' url_template = '{api_url}/showcases/{ident}' model = 'showcases.Showcase' ordered = True def get_is_desktop_app_name(self, obj): return str(_('Desktop App')) if obj.is_desktop_app else '' def get_is_mobile_app_name(self, obj): return str(_('Mobile App')) if obj.is_mobile_app else '' def get_category_name(self, obj): return str(Showcase.CATEGORY_NAMES.get(obj.showcase_category, '')) def get_license_type_name(self, obj): return str(Showcase.LICENSE_TYPE_NAMES.get(obj.license_type, ''))
class SubscribeApiRequest(TopLevel): email = core_fields.Email(required=True, error_messages={ 'invalid': _('E-mail address you entered is not valid') }) personal_data_processing = core_fields.Boolean(required=True) personal_data_use = core_fields.Boolean(required=True) @validates('personal_data_processing') def validate_personal_data_processing(self, value): if not value: raise ValidationError(_('This field is required')) @validates('personal_data_use') def validate_personal_data_use(self, value): if not value: raise ValidationError(_('This field is required')) class Meta: attrs_schema = SubscriptionAttrs
class UserUpdateApiAttrs(ObjectAttrs): fullname = fields.Str() phone = fields.Str() subscriptions_report_opt_in = fields.Boolean() rodo_privacy_policy_opt_in = fields.Boolean() class Meta: strict = True ordered = True object_type = 'user' @post_load def prepare_data(self, data, **kwargs): # TODO: change field names: is_rodo_accepted, is_privacy_policy_accepted or similar. se = data.get('subscriptions_report_opt_in', None) pp = data.get('rodo_privacy_policy_opt_in', None) now = timezone.now() if se is not None: data['subscriptions_report_opt_in'] = now if se else None if pp is not None: data['rodo_privacy_policy_opt_in'] = now if pp else None return data
class ChartApiAttrs(ObjectAttrs): chart = fields.Raw() is_default = fields.Boolean() name = fields.Str() def get_chart(self, obj): return json.dumps(obj.chart) class Meta: relationships_schema = ChartApiRelationships object_type = 'chart' api_path = 'chart' model = 'resources.Chart' url_template = '{api_url}/resources/{data.resource.ident}/charts/{ident}'
class SubscriptionAttrs(schemas.ExtSchema): enable_notifications = fields.Boolean() created = fields.DateTime() modified = fields.DateTime() name = fields.Str(attribute='display_name') object_name = fields.Str(attribute='watcher.object_name') object_url = fields.Method('get_object_url') customfields = fields.Dict() def get_object_url(self, obj): if obj.watcher.watcher_type == 'model': instance = obj.watcher.obj return instance.api_url return ''
class SubscriptionAttrs(ObjectAttrs): email = core_fields.Email(required=True) newsletter_subscription_info = core_fields.String( description='Human readable subscription status', example='Your subscription is active', required=False) is_active = core_fields.Boolean( description='Is newsletter subscription active?', example=True, required=False) class Meta: object_type = 'subscription' strict = True ordered = True
class ArticleApiAttrs(ObjectAttrs, HighlightObjectMixin): slug = TranslatedStr() title = TranslatedStr() notes = TranslatedStr() author = fields.Str(faker_type='firstname') keywords = KeywordsList(TranslatedStr(), faker_type='tagslist') views_count = fields.Integer(faker_type='integer') followed = fields.Boolean() modified = fields.Str(faker_type='datetime') created = fields.Str(faker_type='datetime') license = fields.Nested(ArticleLicense, many=False) category = fields.Nested(ArticleCategory, many=False) class Meta: relationships_schema = ArticleApiRelationships object_type = 'article' url_template = '{api_url}/articles/{ident}' model = 'articles.Article'
class ApplicationApiAttrs(ObjectAttrs): slug = TranslatedStr() title = TranslatedStr() notes = TranslatedStr() author = fields.Str(faker_type='firstname') url = fields.Str(faker_type='url') image_url = fields.Str(faker_type='image_url') image_thumb_url = fields.Str(faker_type='image_thumb_url') followed = fields.Boolean(faker_type='boolean') tags = TranslatedTagsList(TranslatedStr(), faker_type='tagslist') views_count = fields.Integer(faker_type='integer') modified = fields.Str(faker_type='datetime') created = fields.Str(faker_type='datetime') class Meta: relationships_schema = ApplicationApiRelationships object_type = 'application' url_template = '{api_url}/applications/{ident}'
class CreateSubscriptionAttrs(core_schemas.ExtSchema): object_name = core_fields.String(description='Object name', example='resource', required=True, validate=validate.OneOf(choices=ALLOWED_OBJECT_NAMES, error=_('Unsupported object name'))) object_ident = core_fields.String(description='Object ID or query url.', example='12342', required=True) name = core_fields.String(description='Subscription name', example='my query 1', required=False) enable_notifications = core_fields.Boolean(description='Enable notifications', example=True, required=False) customfields = core_fields.Raw() class Meta: strict = True ordered = True @pre_load(pass_many=False) def ident_to_string(self, data): data['object_ident'] = str(data['object_ident']) return data
class DatasetApiAttrs(ObjectAttrs, HighlightObjectMixin): title = TranslatedStr() slug = TranslatedStr() notes = TranslatedStr() categories = fields.Nested(DatasetCategoryAttr, many=True) category = fields.Nested(DatasetCategoryAttr, many=False) formats = fields.List(fields.String()) types = fields.List(fields.String()) keywords = KeywordsList(TranslatedStr()) openness_scores = fields.List(fields.Int()) license_chosen = fields.Integer() license_condition_db_or_copyrighted = fields.String() license_condition_personal_data = fields.String() license_condition_modification = fields.Boolean() license_condition_original = fields.Boolean() license_condition_responsibilities = fields.String() license_condition_source = fields.Boolean() license_condition_timestamp = fields.Boolean() license_name = fields.String() license_description = fields.String() update_frequency = TransUpdateFreqField() views_count =\ fields.Function( lambda obj: obj.computed_views_count if is_enabled('S16_new_date_counters.be') else obj.views_count) downloads_count =\ fields.Function( lambda obj: obj.computed_downloads_count if is_enabled('S16_new_date_counters.be') else obj.downloads_count) url = fields.String() followed = fields.Boolean() modified = fields.DateTime() resource_modified = fields.DateTime() created = fields.DateTime() verified = fields.DateTime() visualization_types = ListWithoutNoneStrElement(fields.Str()) source = fields.Nested(SourceSchema) image_url = fields.Str() image_alt = TranslatedStr() if is_enabled('S35_high_value_data.be'): has_high_value_data = fields.Boolean() if is_enabled('S37_resources_admin_region_data.be'): regions = fields.Nested(RegionSchema, many=True) class Meta: relationships_schema = DatasetApiRelationships object_type = 'dataset' url_template = '{api_url}/datasets/{ident}' model = 'datasets.Dataset'
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
class CommonObjectApiAttrs(ObjectAttrs, HighlightObjectMixin): model = fields.Str() # common slug = TranslatedStr() title = TranslatedStr() notes = TranslatedStr() keywords = KeywordsList(TranslatedStr(), faker_type='tagslist') modified = fields.DateTime() created = fields.DateTime() verified = fields.DateTime() categories = fields.Nested(Category, many=True) category = fields.Nested(Category) if is_enabled('S35_high_value_data.be'): has_high_value_data = fields.Boolean() # datasets source = fields.Nested(SourceSchema) # resources data_date = fields.Date() visualization_types = fields.List(fields.Str()) # applications, showcases author = fields.Str() illustrative_graphics_alt = TranslatedStr() illustrative_graphics_url = fields.Str() image_alt = TranslatedStr() image_thumb_url = fields.Str() if is_enabled('S39_showcases.be'): showcase_category = fields.Str() showcase_category_name = fields.Method('get_showcase_category_name') showcase_types = fields.List(fields.Str()) showcase_platforms = fields.List(fields.Str()) # institutions abbreviation = fields.Str() institution_type = fields.Str() datasets_count = fields.Int(attribute='published_datasets_count') resources_count = fields.Int(attribute='published_resources_count') fax = fields.Str() tel = fields.Str() sources = fields.Nested(DataSourceAttr, many=True) # cms pages html_url = fields.Str() if is_enabled('S39_filter_by_geodata.be'): # regions region_id = fields.Int() hierarchy_label = TranslatedStr() bbox = fields.List(fields.List(fields.Float), attribute='bbox.coordinates') regions = fields.Nested(RegionSchema, many=True) def get_showcase_category_name(self, obj): val = getattr(obj, 'showcase_category', None) if val: model = apps.get_model('showcases.Showcase') return str(model.CATEGORY_NAMES[val]) return missing @staticmethod def self_api_url(data): try: api_url = getattr(settings, 'API_URL', 'https://api.dane.gov.pl') model = data.model obj_id = data.id slug = data['slug'][get_language()] full_url = f'{api_url}/{model}s/{obj_id},{slug}' except AttributeError: full_url = None return full_url class Meta: relationships_schema = CommonObjectRelationships object_type = 'common' api_path = 'search'