Пример #1
0
class TopLevelMeta(schemas.ExtSchema):
    language = fields.String()
    params = fields.Raw()
    path = fields.String()
    count = fields.Integer()
    relative_uri = fields.String()
    aggregations = fields.Raw()
    server_time = fields.DateTime(default=now)
class ErrorsSchema(schemas.ExtSchema):
    jsonapi = fields.Raw(default={'version': '1.0'})
    errors = fields.Nested(ErrorSchema, many=True)

    class Meta:
        strict = True
        ordered = True
Пример #3
0
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 TopLevelMeta(schemas.ExtSchema):
    language = fields.String()
    params = fields.Raw()
    path = fields.String()
    count = fields.Integer()
    relative_uri = fields.String()
    aggregations = fields.Raw()
    subscription_url = fields.String()
    server_time = fields.DateTime(default=now)
    notifications = fields.Raw()

    @pre_dump
    def do_something(self, data, **kwargs):
        request = self.context['request']
        user = getattr(request, 'user', None)
        if user and user.is_authenticated:
            data['notifications'] = user.get_unread_notifications()
        return data
Пример #5
0
class UpdateSubscriptionAttrs(ObjectAttrs):
    name = core_fields.String(description='Subscription name',
                              example='my query 1',
                              required=False)
    customfields = core_fields.Raw()

    class Meta:
        strict = True
        ordered = True
        object_type = 'subscription'
Пример #6
0
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 ChartAttrs(ObjectAttrs):
    resource_id = fields.Int(dump_only=True)
    chart = fields.Raw(required=True)
    is_default = fields.Bool()
    name = fields.Str(required=True, validate=validate.Length(min=1, max=200))

    class Meta:
        object_type = 'chart'
        strict = True
        ordered = True

    @pre_load
    def prepare_data(self, data, **kwargs):
        data.setdefault('is_default', False)
        return data

    @validates_schema
    def validate_schema(self, data, **kwargs):
        chart = self.context.get('chart')
        resource = self.context['resource']
        user = self.context['user']
        if resource.is_chart_creation_blocked and not any(
            [user.is_staff, user.is_superuser]):
            raise ValidationError(
                _('Chart creation for this resource is blocked!'))
        if data['is_default'] and not any([
                user.is_superuser,
                user.is_editor_of_organization(resource.institution)
        ]):
            raise ValidationError(_('No permission to define chart'))
        if chart and chart.is_default != data['is_default']:
            raise ValidationError(_('You cannot change type of chart!'))
        private_charts = resource.charts.filter(is_default=False,
                                                created_by=user)
        if chart:
            private_charts = private_charts.exclude(id=chart.id)
        if not data['is_default'] and private_charts.exists():
            raise ValidationError(_('You cannot add another private chart!'))
        charts_with_same_name = resource.charts.filter(is_default=True,
                                                       name=data['name'])
        if chart:
            charts_with_same_name = charts_with_same_name.exclude(id=chart.id)
        if charts_with_same_name.exists() and data['is_default']:
            raise ValidationError(
                _('You cannot put changes into chart defined by Data Provider. Please provide new chart name.'
                  ))
Пример #8
0
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
Пример #9
0
class ShowcaseProposalCSVSerializer(CSVSerializer):
    id = fields.Int(data_key='id', required=True, example=77)
    category_name = fields.Str(data_key=_('Category'), example='Aplikacja')
    title = fields.Str(data_key=_('Name'), example='Propozycja aplikacji')
    notes = fields.Str(data_key=_('Notes'), default='', example='opis...')
    url = fields.Str(data_key=_('App URL'),
                     default='',
                     example='http://example.com')
    author = fields.Str(data_key=_('Author'),
                        default='',
                        example='Jan Kowalski')
    applicant_email = fields.Email(data_key=_('applicant email'),
                                   default='',
                                   required=False,
                                   example='*****@*****.**')
    keywords = fields.Str(data_key=_('keywords'),
                          attribute='keywords_as_str',
                          default='',
                          example='tag1,tag2,tag3')
    report_date = fields.Date(data_key=_('report date'))
    decision_date = fields.Date(data_key=_('decision date'), default=None)
    comment = fields.Str(data_key=_('comment'),
                         example='komentarz...',
                         default='')
    datasets = fields.Method('get_datasets',
                             data_key=_('datasets'),
                             example='998,999',
                             default='')
    external_datasets = fields.Raw(data_key=_('external datasets'),
                                   example='[]')
    showcase = fields.Int(data_key=_('Showcase'),
                          attribute='showcase.id',
                          default=None)

    class Meta:
        ordered = True
        model = 'showcases.ShowcaseProposal'

    def get_datasets(self, obj):
        return ','.join(str(x.id) for x in obj.datasets.order_by('id'))
Пример #10
0
class CreateSubscriptionAttrs(ObjectAttrs):
    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)
    customfields = core_fields.Raw()

    @pre_load
    def prepare_data(self, data, **kwargs):
        object_ident = data.get('object_ident')
        data['object_ident'] = str(object_ident) if object_ident else None
        object_name = data.get('object_name')
        if object_name and isinstance(object_name, str):
            data['object_name'] = object_name.lower()
        return data

    @validates_schema
    def validate_url(self, data, **kwargs):
        if data['object_name'] == 'query':
            url_split = urlsplit(data['object_ident'])
            api_split = urlsplit(settings.API_URL)
            if url_split.scheme != api_split.scheme or url_split.netloc != api_split.netloc:
                raise ValidationError(_('Invalid url address'),
                                      field_name='object_ident')

    class Meta:
        object_type = 'subscription'
        strict = True
        ordered = True
Пример #11
0
class SubscriptionIncludes(jss.BaseData):
    attributes = fields.Raw()
Пример #12
0
class NotificationIncludes(jss.BaseData):
    attributes = fields.Raw()
Пример #13
0
class DummyAttributes(schemas.ExtSchema):
    dummy = fields.Raw()
Пример #14
0
class Aggregation(schemas.ExtSchema):
    key = fields.Raw()
    title = fields.String()
    doc_count = fields.Integer()
Пример #15
0
class GeoApiMeta(TopLevelMeta):
    data_schema = fields.Raw()
    headers_map = fields.Raw()
    aggregations = fields.Nested(GeoAggregations)
class TopLevel(schemas.ExtSchema):
    included = fields.Raw()
    jsonapi = fields.Raw(default={'version': '1.0'})
    errors = fields.Raw()

    OPTIONS_CLASS = TopLevelOpts

    def __init__(
            self, only=None, exclude=(), many=False, context=None,
            load_only=(), dump_only=(), partial=False, unknown=None,
    ):
        data_cls = self.opts.data_schema or type(
            '{}Data'.format(self.__class__.__name__),
            (Object,), {}
        )
        if self.opts.attrs_schema:
            setattr(data_cls.opts, 'attrs_schema', self.opts.attrs_schema)

        self._declared_fields['data'] = fields.Nested(data_cls, name='data', many=many, allow_none=True)

        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)

    @pre_dump
    def prepare_top_level(self, c, **kwargs):

        def _get_page_link(page_number):
            cleaned_data['page'] = page_number
            return '{}{}?{}'.format(settings.API_URL, request.path, builder.build(cleaned_data))

        c.data = c.data if hasattr(c, 'data') else None
        if not c.data and self.context['is_listing']:
            if isinstance(c.data, es_response.Response):
                c.data.hits = []
            else:
                c.data = []
        request = self.context['request']
        c.meta = getattr(c, 'meta', {})
        c.links = getattr(c, 'links', {})
        cleaned_data = dict(getattr(request.context, 'cleaned_data', {}))

        c.meta.update({
            'language': request.language,
            'params': request.params,
            'path': request.path,
            'relative_uri': request.relative_uri,
        })

        c.links['self'] = request.uri.replace(request.forwarded_prefix, settings.API_URL)

        if self.context['is_listing']:
            data = getattr(c, 'data', {})
            c.meta['aggregations'] = self.get_aggregations(data)
            items_count = self._get_items_count(data)
            c.meta['count'] = items_count
            page, per_page = cleaned_data.get('page', 1), cleaned_data.get('per_page', 20)
            c.links['self'] = _get_page_link(page)
            if page > 1:
                c.links['first'] = _get_page_link(1)
                c.links['prev'] = _get_page_link(page - 1)
            if items_count:
                max_count = min(items_count, self.opts.max_items_num)
                off = 1 if max_count % per_page else 0
                last_page = max_count // per_page + off
                if last_page > 1:
                    c.links['last'] = _get_page_link(last_page)
                if page * per_page < max_count:
                    c.links['next'] = _get_page_link(page + 1)
        return c

    @staticmethod
    def _get_items_count(data):
        if isinstance(data, paginator.Page):
            return data.paginator.count
        elif isinstance(data, list):
            return len(data)
        return data.hits.total if hasattr(data, 'hits') else 0

    def get_aggregations(self, data):
        return getattr(data, 'aggregations', {}) or {}
Пример #17
0
class TableApiMeta(TopLevelMeta):
    data_schema = fields.Raw()
    headers_map = fields.Raw()
Пример #18
0
class ResponseSchema(schemas.ExtSchema):
    jsonapi = fields.Raw(missing=json_api_object, default=json_api_object)
    errors = fields.Raw(required=False)

    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)

        # Top level links
        links_cls = ResponseLinksMany if self.many else ResponseLinksSingle
        self.fields['links'] = Nested(links_cls, name='links',
                                      required=False, many=False, context={'many': self.many})

        # Top level meta
        _meta = getattr(self, 'Meta', None)
        meta_cls = getattr(_meta, 'meta_cls', ResponseMeta)
        if not issubclass(meta_cls, ResponseMeta):
            raise Exception("{} must be a subclass of TopLevelMeta".format(meta_cls.__class__))
        self.fields['meta'] = fields.Nested(meta_cls, name='meta', many=False,
                                            context={'many': self.many},
                                            required=False)

        # Top level data
        data_cls = getattr(_meta, 'data_cls', ResponseData)
        if not issubclass(data_cls, ResponseData):
            raise Exception("{} must be a subclass of ResponseData".format(data_cls.__class__))
        self.fields['data'] = fields.Nested(data_cls, name='data', many=self.many, data_key='data')

    def dump(self, obj, many=None):  # noqa:C901
        marshaller = marshalling.Marshaller()
        errors = {}
        many = self.many if many is None else bool(many)
        processed_obj = obj
        result = None
        if self._has_processors(PRE_DUMP):
            try:
                processed_obj = self._invoke_dump_processors(
                    PRE_DUMP,
                    obj,
                    many,
                    original_data=obj,
                )
            except ValidationError as error:
                errors = error.normalized_messages()

        if not errors:
            try:
                result = marshaller.serialize(
                    processed_obj,
                    self._fields,
                    many=False,
                    accessor=self.get_attribute,
                    dict_class=self.dict_class,
                    index_errors=self.opts.index_errors,
                )
            except ValidationError as error:
                errors = marshaller.errors
                result = error.data

        if not errors and self._has_processors(POST_DUMP):
            try:
                result = self._invoke_dump_processors(
                    POST_DUMP,
                    result,
                    many,
                    original_data=obj,
                )
            except ValidationError as error:
                errors = error.normalized_messages()
        if errors:
            error_field_names = getattr(marshaller, 'error_field_names', [])
            exc = ValidationError(
                errors,
                field_names=error_field_names,
                data=obj,
                valid_data=result,
                **marshaller.error_kwargs
            )
            # User-defined error handler
            self.handle_error(exc, obj)
            raise exc

        return result

    def _do_load(  # noqa:C901
            self, data, many=None, partial=None, unknown=None,
            postprocess=True,
    ):
        errors = {}
        result = None
        processed_data = None
        many = self.many if many is None else bool(many)
        unknown = unknown or self.unknown
        if partial is None:
            partial = self.partial
        if self._has_processors(PRE_LOAD):
            try:
                processed_data = self._invoke_load_processors(
                    PRE_LOAD,
                    data,
                    many,
                    original_data=data,
                )
            except ValidationError as err:
                errors = err.normalized_messages()
        else:
            processed_data = data
        unmarshaller = marshalling.Unmarshaller()
        if not errors:
            result = unmarshaller.deserialize(
                processed_data,
                self._fields,
                many=False,
                partial=partial,
                unknown=unknown,
                dict_class=self.dict_class,
                index_errors=self.opts.index_errors,
            )
            self._invoke_field_validators(unmarshaller, data=result, many=False)
            if self._has_processors(VALIDATES_SCHEMA):
                field_errors = bool(unmarshaller.errors)
                self._invoke_schema_validators(
                    unmarshaller,
                    pass_many=True,
                    data=result,
                    original_data=data,
                    many=many,
                    field_errors=field_errors,
                )
                self._invoke_schema_validators(
                    unmarshaller,
                    pass_many=False,
                    data=result,
                    original_data=data,
                    many=many,
                    field_errors=field_errors,
                )
            errors = unmarshaller.errors
            if not errors and postprocess and self._has_processors(POST_LOAD):
                try:
                    result = self._invoke_load_processors(
                        POST_LOAD,
                        result,
                        many,
                        original_data=data,
                    )
                except ValidationError as err:
                    errors = err.normalized_messages()
        if errors:
            error_field_names = getattr(unmarshaller, 'error_field_names', [])
            exc = ValidationError(
                errors,
                field_names=error_field_names,
                data=data,
                valid_data=result,
                **unmarshaller.error_kwargs
            )
            self.handle_error(exc, data)
            raise exc

        return result

    @property
    def _many(self):
        return False
Пример #19
0
class Geometry(ma.Schema):
    type = fields.String(required=True)
    coordinates = fields.Raw(required=True)