跳转至

Validators

FileSize

Bases: Validator

Validator which succeeds if the file passed to it is within the specified size range. If min is not specified, or is specified as None, no lower bound exists. If max is not specified, or is specified as None, no upper bound exists. The inclusivity of the bounds (if they exist) is configurable. If min_inclusive is not specified, or is specified as True, then the min bound is included in the range. If max_inclusive is not specified, or is specified as True, then the max bound is included in the range.

Examples:

from apiflask import Schema
from apiflask.fields import File
from apiflask.validators import FileSize


class Image(Schema):
    image = File(required=True, validate=FileSize(min='1 MiB', max='2 MiB'))

Parameters:

Name Type Description Default
min Optional[str]

The minimum size (lower bound). If not provided, minimum size will not be checked.

None
max Optional[str]

The maximum size (upper bound). If not provided, maximum size will not be checked.

None
min_inclusive bool

Whether the min bound is included in the range.

True
max_inclusive bool

Whether the max bound is included in the range.

True
error Optional[str]

Error message to raise in case of a validation error. Can be interpolated with {input}, {min} and {max}.

None

Version added: 2.1.0

Source code in apiflask/validators.py
 23
 24
 25
 26
 27
 28
 29
 30
 31
 32
 33
 34
 35
 36
 37
 38
 39
 40
 41
 42
 43
 44
 45
 46
 47
 48
 49
 50
 51
 52
 53
 54
 55
 56
 57
 58
 59
 60
 61
 62
 63
 64
 65
 66
 67
 68
 69
 70
 71
 72
 73
 74
 75
 76
 77
 78
 79
 80
 81
 82
 83
 84
 85
 86
 87
 88
 89
 90
 91
 92
 93
 94
 95
 96
 97
 98
 99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
class FileSize(Validator):
    """Validator which succeeds if the file passed to it is within the specified
    size range. If ``min`` is not specified, or is specified as `None`,
    no lower bound exists. If ``max`` is not specified, or is specified as `None`,
    no upper bound exists. The inclusivity of the bounds (if they exist) is configurable.
    If ``min_inclusive`` is not specified, or is specified as `True`, then
    the ``min`` bound is included in the range. If ``max_inclusive`` is not specified,
    or is specified as `True`, then the ``max`` bound is included in the range.

    Examples:
    ```python
    from apiflask import Schema
    from apiflask.fields import File
    from apiflask.validators import FileSize


    class Image(Schema):
        image = File(required=True, validate=FileSize(min='1 MiB', max='2 MiB'))
    ```

    Arguments:
        min: The minimum size (lower bound). If not provided, minimum
            size will not be checked.
        max: The maximum size (upper bound). If not provided, maximum
            size will not be checked.
        min_inclusive: Whether the `min` bound is included in the range.
        max_inclusive: Whether the `max` bound is included in the range.
        error: Error message to raise in case of a validation error.
            Can be interpolated with `{input}`, `{min}` and `{max}`.

    *Version added: 2.1.0*
    """

    message_min = 'Must be {min_op} {{min}}.'
    message_max = 'Must be {max_op} {{max}}.'
    message_all = 'Must be {min_op} {{min}} and {max_op} {{max}}.'

    message_gte = 'greater than or equal to'
    message_gt = 'greater than'
    message_lte = 'less than or equal to'
    message_lt = 'less than'

    def __init__(
        self,
        min: t.Optional[str] = None,
        max: t.Optional[str] = None,
        min_inclusive: bool = True,
        max_inclusive: bool = True,
        error: t.Optional[str] = None,
    ) -> None:
        self.min = min
        self.max = max
        self.min_size = parse_size(self.min) if self.min else None
        self.max_size = parse_size(self.max) if self.max else None
        self.min_inclusive = min_inclusive
        self.max_inclusive = max_inclusive
        self.error = error

        self.message_min = self.message_min.format(
            min_op=self.message_gte if self.min_inclusive else self.message_gt
        )
        self.message_max = self.message_max.format(
            max_op=self.message_lte if self.max_inclusive else self.message_lt
        )
        self.message_all = self.message_all.format(
            min_op=self.message_gte if self.min_inclusive else self.message_gt,
            max_op=self.message_lte if self.max_inclusive else self.message_lt,
        )

    def _repr_args(self) -> str:
        return 'min={!r}, max={!r}, min_inclusive={!r}, max_inclusive={!r}'.format(
            self.min, self.max, self.min_inclusive, self.max_inclusive
        )

    def _format_error(self, value: FileStorage, message: str) -> str:
        return (self.error or message).format(input=value, min=self.min, max=self.max)

    def __call__(self, value: FileStorage) -> FileStorage:
        if not isinstance(value, FileStorage):
            raise TypeError(
                f'A FileStorage object is required, not {type(value).__name__!r}'
            )

        file_size = get_filestorage_size(value)
        if self.min_size is not None and (
            file_size < self.min_size if self.min_inclusive else file_size <= self.min_size
        ):
            message = self.message_min if self.max is None else self.message_all
            raise ValidationError(self._format_error(value, message))

        if self.max_size is not None and (
            file_size > self.max_size if self.max_inclusive else file_size >= self.max_size
        ):
            message = self.message_max if self.min is None else self.message_all
            raise ValidationError(self._format_error(value, message))

        return value

FileType

Bases: Validator

Validator which succeeds if the uploaded file is allowed by a given list of extensions.

Examples:

from apiflask import Schema
from apiflask.fields import File
from apiflask.validators import FileType


class Image(Schema):
    image = File(required=True, validate=FileType(['.png']))

Parameters:

Name Type Description Default
accept Iterable[str]

A sequence of allowed extensions.

required
error Optional[str]

Error message to raise in case of a validation error. Can be interpolated with {input} and {extensions}.

None

Version added: 2.1.0

Source code in apiflask/validators.py
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
class FileType(Validator):
    """Validator which succeeds if the uploaded file is allowed by a given list
        of extensions.

    Examples:
    ```python
    from apiflask import Schema
    from apiflask.fields import File
    from apiflask.validators import FileType


    class Image(Schema):
        image = File(required=True, validate=FileType(['.png']))
    ```

    Arguments:
        accept: A sequence of allowed extensions.
        error: Error message to raise in case of a validation error.
            Can be interpolated with `{input}` and `{extensions}`.

    *Version added: 2.1.0*
    """

    default_message = 'Not an allowed file type. Allowed file types: [{extensions}]'

    def __init__(
        self,
        accept: t.Iterable[str],
        error: t.Optional[str] = None,
    ) -> None:
        self.allowed_types = {ext.lower() for ext in accept}
        self.error = error or self.default_message

    def _format_error(self, value: FileStorage) -> str:
        return (self.error or self.default_message).format(
            input=value,
            extensions=''.join(self.allowed_types)
        )

    def __call__(self, value: FileStorage) -> FileStorage:
        if not isinstance(value, FileStorage):
            raise TypeError(
                f'A FileStorage object is required, not {type(value).__name__!r}'
            )

        _, extension = os.path.splitext(value.filename) if value.filename else (None, None)
        if extension is None or extension.lower() not in self.allowed_types:
            raise ValidationError(self._format_error(value))

        return value

External documentation

Check out the Validator API documentation for the validators from marshmallow.