• Home
  • Features
  • Pricing
  • Docs
  • Announcements
  • Sign In

LeanderCS / flask-inputfilter / #396

24 May 2025 03:18PM UTC coverage: 93.409%. Remained the same
#396

push

coveralls-python

LeanderCS
Fix autobuild of docs

1885 of 2018 relevant lines covered (93.41%)

0.93 hits per line

Source File
Press 'n' to go to next uncovered line, 'b' for previous

76.38
/flask_inputfilter/input_filter.py
1
from __future__ import annotations
1✔
2

3
import json
1✔
4
import logging
1✔
5
from collections.abc import Callable
1✔
6
from typing import Any, Dict, List, Optional, Type, TypeVar, Union
1✔
7

8
from flask import Response, g, request
1✔
9

10
from flask_inputfilter.conditions import BaseCondition
1✔
11
from flask_inputfilter.exceptions import ValidationError
1✔
12
from flask_inputfilter.filters import BaseFilter
1✔
13
from flask_inputfilter.mixins import ExternalApiMixin, FieldMixin
1✔
14
from flask_inputfilter.models import ExternalApiConfig, FieldModel
1✔
15
from flask_inputfilter.validators import BaseValidator
1✔
16

17
T = TypeVar("T")
1✔
18

19

20
class InputFilter:
1✔
21
    """Base class for all input filters."""
22

23
    def __init__(self, methods: Optional[List[str]] = None) -> None:
1✔
24
        self.methods: List[str] = methods or [
1✔
25
            "GET",
26
            "POST",
27
            "PATCH",
28
            "PUT",
29
            "DELETE",
30
        ]
31
        self.fields: Dict[str, FieldModel] = {}
1✔
32
        self.conditions: List[BaseCondition] = []
1✔
33
        self.global_filters: List[BaseFilter] = []
1✔
34
        self.global_validators: List[BaseValidator] = []
1✔
35
        self.data: Dict[str, Any] = {}
1✔
36
        self.validated_data: Dict[str, Any] = {}
1✔
37
        self.errors: Dict[str, str] = {}
1✔
38
        self.model_class: Optional[Type[T]] = None
1✔
39

40
    def isValid(self) -> bool:
1✔
41
        """
42
        Checks if the object's state or its attributes meet certain conditions
43
        to be considered valid. This function is typically used to ensure that
44
        the current state complies with specific requirements or rules.
45

46
        Returns:
47
            bool: Returns True if the state or attributes of the object fulfill
48
                all required conditions; otherwise, returns False.
49
        """
50
        import warnings
×
51

52
        warnings.warn(
×
53
            "isValid() is deprecated, use is_valid() instead",
54
            DeprecationWarning,
55
            stacklevel=2,
56
        )
57
        return self.is_valid()
×
58

59
    def is_valid(self) -> bool:
1✔
60
        """
61
        Checks if the object's state or its attributes meet certain conditions
62
        to be considered valid. This function is typically used to ensure that
63
        the current state complies with specific requirements or rules.
64

65
        Returns:
66
            bool: Returns True if the state or attributes of the object fulfill
67
                all required conditions; otherwise, returns False.
68
        """
69
        try:
1✔
70
            self.validate_data()
1✔
71

72
        except ValidationError as e:
1✔
73
            self.errors = e.args[0]
1✔
74
            return False
1✔
75

76
        return True
1✔
77

78
    @classmethod
1✔
79
    def validate(
80
        cls,
81
    ) -> Callable[
82
        [Any],
83
        Callable[
84
            [tuple[Any, ...], Dict[str, Any]],
85
            Union[Response, tuple[Any, Dict[str, Any]]],
86
        ],
87
    ]:
88
        """
89
        Decorator for validating input data in routes.
90

91
        Args:
92
            cls
93

94
        Returns:
95
            Callable[
96
                [Any],
97
                Callable[
98
                    [tuple[Any, ...], Dict[str, Any]],
99
                    Union[Response, tuple[Any, Dict[str, Any]]],
100
                ],
101
            ]
102
        """
103

104
        def decorator(
1✔
105
            f: Callable,
106
        ) -> Callable[[Any, Any], Union[Response, tuple[Any, Dict[str, Any]]]]:
107
            """
108
            Decorator function to validate input data for a Flask route.
109

110
            Args:
111
                f (Callable): The Flask route function to be decorated.
112

113
            Returns:
114
                Callable[
115
                    [Any, Any],
116
                    Union[
117
                        Response,
118
                        tuple[Any, Dict[str, Any]]
119
                    ]
120
                ]: The wrapped function with input validation.
121
            """
122

123
            def wrapper(
1✔
124
                *args, **kwargs
125
            ) -> Union[Response, tuple[Any, Dict[str, Any]]]:
126
                """
127
                Wrapper function to handle input validation and error handling
128
                for the decorated route function.
129

130
                Args:
131
                    *args: Positional arguments for the route function.
132
                    **kwargs: Keyword arguments for the route function.
133

134
                Returns:
135
                    Union[Response, tuple[Any, Dict[str, Any]]]: The response
136
                        from the route function or an error response.
137
                """
138
                input_filter = cls()
1✔
139
                if request.method not in input_filter.methods:
1✔
140
                    return Response(status=405, response="Method Not Allowed")
1✔
141

142
                data = request.json if request.is_json else request.args
1✔
143

144
                try:
1✔
145
                    kwargs = kwargs or {}
1✔
146

147
                    input_filter.data = {**data, **kwargs}
1✔
148

149
                    g.validated_data = input_filter.validateData()
1✔
150

151
                except ValidationError as e:
1✔
152
                    return Response(
1✔
153
                        status=400,
154
                        response=json.dumps(e.args[0]),
155
                        mimetype="application/json",
156
                    )
157

158
                except Exception:
×
159
                    logging.getLogger(__name__).exception(
×
160
                        "An unexpected exception occurred while "
161
                        "validating input data.",
162
                    )
163
                    return Response(status=500)
×
164

165
                return f(*args, **kwargs)
1✔
166

167
            return wrapper
1✔
168

169
        return decorator
1✔
170

171
    def validateData(
1✔
172
        self, data: Optional[Dict[str, Any]] = None
173
    ) -> Union[Dict[str, Any], Type[T]]:
174
        """
175
        Validates input data against defined field rules, including applying
176
        filters, validators, custom logic steps, and fallback mechanisms. The
177
        validation process also ensures the required fields are handled
178
        appropriately and conditions are checked after processing.
179

180
        Args:
181
            data (Dict[str, Any]): A dictionary containing the input data to
182
                be validated where keys represent field names and values
183
                represent the corresponding data.
184

185
        Returns:
186
            Union[Dict[str, Any], Type[T]]: A dictionary containing the
187
                validated data with any modifications, default values,
188
                or processed values as per the defined validation rules.
189

190
        Raises:
191
            Any errors raised during external API calls, validation, or
192
                logical steps execution of the respective fields or conditions
193
                will propagate without explicit handling here.
194
        """
195
        import warnings
1✔
196

197
        warnings.warn(
1✔
198
            "validateData() is deprecated, use validate_data() instead",
199
            DeprecationWarning,
200
            stacklevel=2,
201
        )
202
        return self.validate_data(data)
1✔
203

204
    def validate_data(
1✔
205
        self, data: Optional[Dict[str, Any]] = None
206
    ) -> Union[Dict[str, Any], Type[T]]:
207
        """
208
        Validates input data against defined field rules, including applying
209
        filters, validators, custom logic steps, and fallback mechanisms. The
210
        validation process also ensures the required fields are handled
211
        appropriately and conditions are checked after processing.
212

213
        Args:
214
            data (Dict[str, Any]): A dictionary containing the input data to
215
                be validated where keys represent field names and values
216
                represent the corresponding data.
217

218
        Returns:
219
            Union[Dict[str, Any], Type[T]]: A dictionary containing the
220
                validated data with any modifications, default values,
221
                or processed values as per the defined validation rules.
222

223
        Raises:
224
            Any errors raised during external API calls, validation, or
225
                logical steps execution of the respective fields or conditions
226
                will propagate without explicit handling here.
227
        """
228
        data = data or self.data
1✔
229
        errors = {}
1✔
230

231
        for field_name, field_info in self.fields.items():
1✔
232
            value = data.get(field_name)
1✔
233

234
            required = field_info.required
1✔
235
            default = field_info.default
1✔
236
            fallback = field_info.fallback
1✔
237
            filters = field_info.filters + self.global_filters
1✔
238
            validators = field_info.validators + self.global_validators
1✔
239
            steps = field_info.steps
1✔
240
            external_api = field_info.external_api
1✔
241
            copy = field_info.copy
1✔
242

243
            try:
1✔
244
                if copy:
1✔
245
                    value = self.validated_data.get(copy)
1✔
246

247
                if external_api:
1✔
248
                    value = ExternalApiMixin.call_external_api(
1✔
249
                        external_api, fallback, self.validated_data
250
                    )
251

252
                value = FieldMixin.apply_filters(filters, value)
1✔
253
                value = (
1✔
254
                    FieldMixin.validate_field(validators, fallback, value)
255
                    or value
256
                )
257
                value = FieldMixin.apply_steps(steps, fallback, value) or value
1✔
258
                value = FieldMixin.check_for_required(
1✔
259
                    field_name, required, default, fallback, value
260
                )
261

262
                self.validated_data[field_name] = value
1✔
263

264
            except ValidationError as e:
1✔
265
                errors[field_name] = str(e)
1✔
266

267
        try:
1✔
268
            FieldMixin.check_conditions(self.conditions, self.validated_data)
1✔
269
        except ValidationError as e:
1✔
270
            errors["_condition"] = str(e)
1✔
271

272
        if errors:
1✔
273
            raise ValidationError(errors)
1✔
274

275
        if self.model_class is not None:
1✔
276
            return self.serialize()
1✔
277

278
        return self.validated_data
1✔
279

280
    def addCondition(self, condition: BaseCondition) -> None:
1✔
281
        """
282
        Add a condition to the input filter.
283

284
        Args:
285
            condition (BaseCondition): The condition to add.
286
        """
287
        import warnings
×
288

289
        warnings.warn(
×
290
            "addCondition() is deprecated, use add_condition() instead",
291
            DeprecationWarning,
292
            stacklevel=2,
293
        )
294
        self.add_condition(condition)
×
295

296
    def add_condition(self, condition: BaseCondition) -> None:
1✔
297
        """
298
        Add a condition to the input filter.
299

300
        Args:
301
            condition (BaseCondition): The condition to add.
302
        """
303
        self.conditions.append(condition)
1✔
304

305
    def getConditions(self) -> List[BaseCondition]:
1✔
306
        """
307
        Retrieve the list of all registered conditions.
308

309
        This function provides access to the conditions that have been
310
        registered and stored. Each condition in the returned list
311
        is represented as an instance of the BaseCondition type.
312

313
        Returns:
314
            List[BaseCondition]: A list containing all currently registered
315
                instances of BaseCondition.
316
        """
317
        import warnings
×
318

319
        warnings.warn(
×
320
            "getConditions() is deprecated, use get_conditions() instead",
321
            DeprecationWarning,
322
            stacklevel=2,
323
        )
324
        return self.get_conditions()
×
325

326
    def get_conditions(self) -> List[BaseCondition]:
1✔
327
        """
328
        Retrieve the list of all registered conditions.
329

330
        This function provides access to the conditions that have been
331
        registered and stored. Each condition in the returned list
332
        is represented as an instance of the BaseCondition type.
333

334
        Returns:
335
            List[BaseCondition]: A list containing all currently registered
336
                instances of BaseCondition.
337
        """
338
        return self.conditions
1✔
339

340
    def setData(self, data: Dict[str, Any]) -> None:
1✔
341
        """
342
        Filters and sets the provided data into the object's internal storage,
343
        ensuring that only the specified fields are considered and their values
344
        are processed through defined filters.
345

346
        Parameters:
347
            data (Dict[str, Any]):
348
                The input dictionary containing key-value pairs where keys
349
                represent field names and values represent the associated
350
                data to be filtered and stored.
351
        """
352
        import warnings
×
353

354
        warnings.warn(
×
355
            "setData() is deprecated, use set_data() instead",
356
            DeprecationWarning,
357
            stacklevel=2,
358
        )
359
        self.set_data(data)
×
360

361
    def set_data(self, data: Dict[str, Any]) -> None:
1✔
362
        """
363
        Filters and sets the provided data into the object's internal storage,
364
        ensuring that only the specified fields are considered and their values
365
        are processed through defined filters.
366

367
        Parameters:
368
            data (Dict[str, Any]):
369
                The input dictionary containing key-value pairs where keys
370
                represent field names and values represent the associated
371
                data to be filtered and stored.
372
        """
373
        self.data = {}
1✔
374
        for field_name, field_value in data.items():
1✔
375
            if field_name in self.fields:
1✔
376
                field_value = FieldMixin.apply_filters(
1✔
377
                    filters=self.fields[field_name].filters,
378
                    value=field_value,
379
                )
380

381
            self.data[field_name] = field_value
1✔
382

383
    def getValue(self, name: str) -> Any:
1✔
384
        """
385
        This method retrieves a value associated with the provided name. It
386
        searches for the value based on the given identifier and returns the
387
        corresponding result. If no value is found, it typically returns a
388
        default or fallback output. The method aims to provide flexibility in
389
        retrieving data without explicitly specifying the details of the
390
        underlying implementation.
391

392
        Args:
393
            name (str): A string that represents the identifier for which the
394
                 corresponding value is being retrieved. It is used to perform
395
                 the lookup.
396

397
        Returns:
398
            Any: The retrieved value associated with the given name. The
399
                 specific type of this value is dependent on the
400
                 implementation and the data being accessed.
401
        """
402
        import warnings
×
403

404
        warnings.warn(
×
405
            "getValue() is deprecated, use get_value() instead",
406
            DeprecationWarning,
407
            stacklevel=2,
408
        )
409
        return self.get_value(name)
×
410

411
    def get_value(self, name: str) -> Any:
1✔
412
        """
413
        This method retrieves a value associated with the provided name. It
414
        searches for the value based on the given identifier and returns the
415
        corresponding result. If no value is found, it typically returns a
416
        default or fallback output. The method aims to provide flexibility in
417
        retrieving data without explicitly specifying the details of the
418
        underlying implementation.
419

420
        Args:
421
            name (str): A string that represents the identifier for which the
422
                 corresponding value is being retrieved. It is used to perform
423
                 the lookup.
424

425
        Returns:
426
            Any: The retrieved value associated with the given name. The
427
                 specific type of this value is dependent on the
428
                 implementation and the data being accessed.
429
        """
430
        return self.validated_data.get(name)
1✔
431

432
    def getValues(self) -> Dict[str, Any]:
1✔
433
        """
434
        Retrieves a dictionary of key-value pairs from the current object. This
435
        method provides access to the internal state or configuration of the
436
        object in a dictionary format, where keys are strings and values can be
437
        of various types depending on the object's design.
438

439
        Returns:
440
            Dict[str, Any]: A dictionary containing string keys and their
441
                            corresponding values of any data type.
442
        """
443
        import warnings
×
444

445
        warnings.warn(
×
446
            "getValues() is deprecated, use get_values() instead",
447
            DeprecationWarning,
448
            stacklevel=2,
449
        )
450
        return self.get_values()
×
451

452
    def get_values(self) -> Dict[str, Any]:
1✔
453
        """
454
        Retrieves a dictionary of key-value pairs from the current object. This
455
        method provides access to the internal state or configuration of the
456
        object in a dictionary format, where keys are strings and values can be
457
        of various types depending on the object's design.
458

459
        Returns:
460
            Dict[str, Any]: A dictionary containing string keys and their
461
                            corresponding values of any data type.
462
        """
463
        return self.validated_data
1✔
464

465
    def getRawValue(self, name: str) -> Any:
1✔
466
        """
467
        Fetches the raw value associated with the provided key.
468

469
        This method is used to retrieve the underlying value linked to the
470
        given key without applying any transformations or validations. It
471
        directly fetches the raw stored value and is typically used in
472
        scenarios where the raw data is needed for processing or debugging
473
        purposes.
474

475
        Args:
476
            name (str): The name of the key whose raw value is to be
477
                retrieved.
478

479
        Returns:
480
            Any: The raw value associated with the provided key.
481
        """
482
        import warnings
×
483

484
        warnings.warn(
×
485
            "getRawValue() is deprecated, use get_raw_value() instead",
486
            DeprecationWarning,
487
            stacklevel=2,
488
        )
489
        return self.get_raw_value(name)
×
490

491
    def get_raw_value(self, name: str) -> Any:
1✔
492
        """
493
        Fetches the raw value associated with the provided key.
494

495
        This method is used to retrieve the underlying value linked to the
496
        given key without applying any transformations or validations. It
497
        directly fetches the raw stored value and is typically used in
498
        scenarios where the raw data is needed for processing or debugging
499
        purposes.
500

501
        Args:
502
            name (str): The name of the key whose raw value is to be
503
                retrieved.
504

505
        Returns:
506
            Any: The raw value associated with the provided key.
507
        """
508
        return self.data.get(name)
1✔
509

510
    def getRawValues(self) -> Dict[str, Any]:
1✔
511
        """
512
        Retrieves raw values from a given source and returns them as a
513
        dictionary.
514

515
        This method is used to fetch and return unprocessed or raw data in
516
        the form of a dictionary where the keys are strings, representing
517
        the identifiers, and the values are of any data type.
518

519
        Returns:
520
            Dict[str, Any]: A dictionary containing the raw values retrieved.
521
               The keys are strings representing the identifiers, and the
522
               values can be of any type, depending on the source
523
               being accessed.
524
        """
525
        import warnings
×
526

527
        warnings.warn(
×
528
            "getRawValues() is deprecated, use get_raw_values() instead",
529
            DeprecationWarning,
530
            stacklevel=2,
531
        )
532
        return self.get_raw_values()
×
533

534
    def get_raw_values(self) -> Dict[str, Any]:
1✔
535
        """
536
        Retrieves raw values from a given source and returns them as a
537
        dictionary.
538

539
        This method is used to fetch and return unprocessed or raw data in
540
        the form of a dictionary where the keys are strings, representing
541
        the identifiers, and the values are of any data type.
542

543
        Returns:
544
            Dict[str, Any]: A dictionary containing the raw values retrieved.
545
               The keys are strings representing the identifiers, and the
546
               values can be of any type, depending on the source
547
               being accessed.
548
        """
549
        if not self.fields:
1✔
550
            return {}
1✔
551

552
        return {
1✔
553
            field: self.data[field]
554
            for field in self.fields
555
            if field in self.data
556
        }
557

558
    def getUnfilteredData(self) -> Dict[str, Any]:
1✔
559
        """
560
        Fetches unfiltered data from the data source.
561

562
        This method retrieves data without any filtering, processing, or
563
        manipulations applied. It is intended to provide raw data that has
564
        not been altered since being retrieved from its source. The usage
565
        of this method should be limited to scenarios where unprocessed data
566
        is required, as it does not perform any validations or checks.
567

568
        Returns:
569
            Dict[str, Any]: The unfiltered, raw data retrieved from the
570
                 data source. The return type may vary based on the
571
                 specific implementation of the data source.
572
        """
573
        import warnings
×
574

575
        warnings.warn(
×
576
            "getUnfilteredData() is deprecated, use "
577
            "get_unfiltered_data() instead",
578
            DeprecationWarning,
579
            stacklevel=2,
580
        )
581
        return self.get_unfiltered_data()
×
582

583
    def get_unfiltered_data(self) -> Dict[str, Any]:
1✔
584
        """
585
        Fetches unfiltered data from the data source.
586

587
        This method retrieves data without any filtering, processing, or
588
        manipulations applied. It is intended to provide raw data that has
589
        not been altered since being retrieved from its source. The usage
590
        of this method should be limited to scenarios where unprocessed data
591
        is required, as it does not perform any validations or checks.
592

593
        Returns:
594
            Dict[str, Any]: The unfiltered, raw data retrieved from the
595
                 data source. The return type may vary based on the
596
                 specific implementation of the data source.
597
        """
598
        return self.data
1✔
599

600
    def setUnfilteredData(self, data: Dict[str, Any]) -> None:
1✔
601
        """
602
        Sets unfiltered data for the current instance. This method assigns a
603
        given dictionary of data to the instance for further processing. It
604
        updates the internal state using the provided data.
605

606
        Parameters:
607
            data (Dict[str, Any]): A dictionary containing the unfiltered
608
                data to be associated with the instance.
609
        """
610
        import warnings
×
611

612
        warnings.warn(
×
613
            "setUnfilteredData() is deprecated, use "
614
            "set_unfiltered_data() instead",
615
            DeprecationWarning,
616
            stacklevel=2,
617
        )
618
        self.set_unfiltered_data(data)
×
619

620
    def set_unfiltered_data(self, data: Dict[str, Any]) -> None:
1✔
621
        """
622
        Sets unfiltered data for the current instance. This method assigns a
623
        given dictionary of data to the instance for further processing. It
624
        updates the internal state using the provided data.
625

626
        Parameters:
627
            data (Dict[str, Any]): A dictionary containing the unfiltered
628
                data to be associated with the instance.
629
        """
630
        self.data = data
1✔
631

632
    def hasUnknown(self) -> bool:
1✔
633
        """
634
        Checks whether any values in the current data do not have corresponding
635
        configurations in the defined fields.
636

637
        Returns:
638
            bool: True if there are any unknown fields; False otherwise.
639
        """
640
        import warnings
×
641

642
        warnings.warn(
×
643
            "hasUnknown() is deprecated, use has_unknown() instead",
644
            DeprecationWarning,
645
            stacklevel=2,
646
        )
647
        return self.has_unknown()
×
648

649
    def has_unknown(self) -> bool:
1✔
650
        """
651
        Checks whether any values in the current data do not have corresponding
652
        configurations in the defined fields.
653

654
        Returns:
655
            bool: True if there are any unknown fields; False otherwise.
656
        """
657
        if not self.data and self.fields:
1✔
658
            return True
1✔
659

660
        return any(
1✔
661
            field_name not in self.fields.keys()
662
            for field_name in self.data.keys()
663
        )
664

665
    def getErrorMessage(self, field_name: str) -> Optional[str]:
1✔
666
        """
667
        Retrieves and returns a predefined error message.
668

669
        This method is intended to provide a consistent error message
670
        to be used across the application when an error occurs. The
671
        message is predefined and does not accept any parameters.
672
        The exact content of the error message may vary based on
673
        specific implementation, but it is designed to convey meaningful
674
        information about the nature of an error.
675

676
        Args:
677
            field_name (str): The name of the field for which the error
678
                message is being retrieved.
679

680
        Returns:
681
            Optional[str]: A string representing the predefined error message.
682
        """
683
        import warnings
×
684

685
        warnings.warn(
×
686
            "getErrorMessage() is deprecated, use get_error_message() instead",
687
            DeprecationWarning,
688
            stacklevel=2,
689
        )
690
        return self.get_error_message(field_name)
×
691

692
    def get_error_message(self, field_name: str) -> Optional[str]:
1✔
693
        """
694
        Retrieves and returns a predefined error message.
695

696
        This method is intended to provide a consistent error message
697
        to be used across the application when an error occurs. The
698
        message is predefined and does not accept any parameters.
699
        The exact content of the error message may vary based on
700
        specific implementation, but it is designed to convey meaningful
701
        information about the nature of an error.
702

703
        Args:
704
            field_name (str): The name of the field for which the error
705
                message is being retrieved.
706

707
        Returns:
708
            Optional[str]: A string representing the predefined error message.
709
        """
710
        return self.errors.get(field_name)
1✔
711

712
    def getErrorMessages(self) -> Dict[str, str]:
1✔
713
        """
714
        Retrieves all error messages associated with the fields in the input
715
        filter.
716

717
        This method aggregates and returns a dictionary of error messages
718
        where the keys represent field names, and the values are their
719
        respective error messages.
720

721
        Returns:
722
            Dict[str, str]: A dictionary containing field names as keys and
723
                            their corresponding error messages as values.
724
        """
725
        import warnings
×
726

727
        warnings.warn(
×
728
            "getErrorMessages() is deprecated, use "
729
            "get_error_messages() instead",
730
            DeprecationWarning,
731
            stacklevel=2,
732
        )
733
        return self.get_error_messages()
×
734

735
    def get_error_messages(self) -> Dict[str, str]:
1✔
736
        """
737
        Retrieves all error messages associated with the fields in the input
738
        filter.
739

740
        This method aggregates and returns a dictionary of error messages
741
        where the keys represent field names, and the values are their
742
        respective error messages.
743

744
        Returns:
745
            Dict[str, str]: A dictionary containing field names as keys and
746
                            their corresponding error messages as values.
747
        """
748
        return self.errors
1✔
749

750
    def add(
1✔
751
        self,
752
        name: str,
753
        required: bool = False,
754
        default: Any = None,
755
        fallback: Any = None,
756
        filters: Optional[List[BaseFilter]] = None,
757
        validators: Optional[List[BaseValidator]] = None,
758
        steps: Optional[List[Union[BaseFilter, BaseValidator]]] = None,
759
        external_api: Optional[ExternalApiConfig] = None,
760
        copy: Optional[str] = None,
761
    ) -> None:
762
        """
763
        Add the field to the input filter.
764

765
        Args:
766
            name (str): The name of the field.
767

768
            required (Optional[bool]): Whether the field is required.
769

770
            default (Optional[Any]): The default value of the field.
771

772
            fallback (Optional[Any]): The fallback value of the field, if
773
                validations fails or field None, although it is required.
774

775
            filters (Optional[List[BaseFilter]]): The filters to apply to
776
                the field value.
777

778
            validators (Optional[List[BaseValidator]]): The validators to
779
                apply to the field value.
780

781
            steps (Optional[List[Union[BaseFilter, BaseValidator]]]): Allows
782
                to apply multiple filters and validators in a specific order.
783

784
            external_api (Optional[ExternalApiConfig]): Configuration for an
785
                external API call.
786

787
            copy (Optional[str]): The name of the field to copy the value
788
                from.
789
        """
790
        if name in self.fields:
1✔
791
            raise ValueError(f"Field '{name}' already exists.")
1✔
792

793
        self.fields[name] = FieldModel(
1✔
794
            required=required,
795
            default=default,
796
            fallback=fallback,
797
            filters=filters or [],
798
            validators=validators or [],
799
            steps=steps or [],
800
            external_api=external_api,
801
            copy=copy,
802
        )
803

804
    def has(self, field_name: str) -> bool:
1✔
805
        """
806
        This method checks the existence of a specific field within the input
807
        filter values, identified by its field name. It does not return a
808
        value, serving purely as a validation or existence check mechanism.
809

810
        Args:
811
            field_name (str): The name of the field to check for existence.
812

813
        Returns:
814
            bool: True if the field exists in the input filter,
815
                otherwise False.
816
        """
817
        return field_name in self.fields
1✔
818

819
    def getInput(self, field_name: str) -> Optional[FieldModel]:
1✔
820
        """
821
        Represents a method to retrieve a field by its name.
822

823
        This method allows fetching the configuration of a specific field
824
        within the object, using its name as a string. It ensures
825
        compatibility with various field names and provides a generic
826
        return type to accommodate different data types for the fields.
827

828
        Args:
829
            field_name (str): A string representing the name of the field who
830
                        needs to be retrieved.
831

832
        Returns:
833
            Optional[FieldModel]: The field corresponding to the
834
                specified name.
835
        """
836
        import warnings
×
837

838
        warnings.warn(
×
839
            "getInput() is deprecated, use get_input() instead",
840
            DeprecationWarning,
841
            stacklevel=2,
842
        )
843
        return self.get_input(field_name)
×
844

845
    def get_input(self, field_name: str) -> Optional[FieldModel]:
1✔
846
        """
847
        Represents a method to retrieve a field by its name.
848

849
        This method allows fetching the configuration of a specific field
850
        within the object, using its name as a string. It ensures
851
        compatibility with various field names and provides a generic
852
        return type to accommodate different data types for the fields.
853

854
        Args:
855
            field_name (str): A string representing the name of the field who
856
                        needs to be retrieved.
857

858
        Returns:
859
            Optional[FieldModel]: The field corresponding to the
860
                specified name.
861
        """
862
        return self.fields.get(field_name)
1✔
863

864
    def getInputs(self) -> Dict[str, FieldModel]:
1✔
865
        """
866
        Retrieve the dictionary of input fields associated with the object.
867

868
        Returns:
869
            Dict[str, FieldModel]: Dictionary containing field names as
870
                keys and their corresponding FieldModel instances as values
871
        """
872
        import warnings
1✔
873

874
        warnings.warn(
1✔
875
            "getInputs() is deprecated, use get_inputs() instead",
876
            DeprecationWarning,
877
            stacklevel=2,
878
        )
879
        return self.get_inputs()
1✔
880

881
    def get_inputs(self) -> Dict[str, FieldModel]:
1✔
882
        """
883
        Retrieve the dictionary of input fields associated with the object.
884

885
        Returns:
886
            Dict[str, FieldModel]: Dictionary containing field names as
887
                keys and their corresponding FieldModel instances as values
888
        """
889
        return self.fields
1✔
890

891
    def remove(self, field_name: str) -> Optional[FieldModel]:
1✔
892
        """
893
        Removes the specified field from the instance or collection.
894

895
        This method is used to delete a specific field identified by
896
        its name. It ensures the designated field is removed entirely
897
        from the relevant data structure. No value is returned upon
898
        successful execution.
899

900
        Args:
901
            field_name (str): The name of the field to be removed.
902

903
        Returns:
904
            Any: The value of the removed field, if any.
905
        """
906
        return self.fields.pop(field_name, None)
1✔
907

908
    def count(self) -> int:
1✔
909
        """
910
        Counts the total number of elements in the collection.
911

912
        This method returns the total count of elements stored within the
913
        underlying data structure, providing a quick way to ascertain the
914
        size or number of entries available.
915

916
        Returns:
917
            int: The total number of elements in the collection.
918
        """
919
        return len(self.fields)
1✔
920

921
    def replace(
1✔
922
        self,
923
        name: str,
924
        required: bool = False,
925
        default: Any = None,
926
        fallback: Any = None,
927
        filters: Optional[List[BaseFilter]] = None,
928
        validators: Optional[List[BaseValidator]] = None,
929
        steps: Optional[List[Union[BaseFilter, BaseValidator]]] = None,
930
        external_api: Optional[ExternalApiConfig] = None,
931
        copy: Optional[str] = None,
932
    ) -> None:
933
        """
934
        Replaces a field in the input filter.
935

936
        Args:
937
             name (str): The name of the field.
938

939
            required (Optional[bool]): Whether the field is required.
940

941
            default (Optional[Any]): The default value of the field.
942

943
            fallback (Optional[Any]): The fallback value of the field, if
944
                validations fails or field None, although it is required.
945

946
            filters (Optional[List[BaseFilter]]): The filters to apply to
947
                the field value.
948

949
            validators (Optional[List[BaseValidator]]): The validators to
950
                apply to the field value.
951

952
            steps (Optional[List[Union[BaseFilter, BaseValidator]]]): Allows
953
                to apply multiple filters and validators in a specific order.
954

955
            external_api (Optional[ExternalApiConfig]): Configuration for an
956
                external API call.
957

958
            copy (Optional[str]): The name of the field to copy the value
959
                from.
960
        """
961
        self.fields[name] = FieldModel(
1✔
962
            required=required,
963
            default=default,
964
            fallback=fallback,
965
            filters=filters or [],
966
            validators=validators or [],
967
            steps=steps or [],
968
            external_api=external_api,
969
            copy=copy,
970
        )
971

972
    def addGlobalFilter(self, filter: BaseFilter) -> None:
1✔
973
        """
974
        Add a global filter to be applied to all fields.
975

976
        Args:
977
            filter: The filter to add.
978
        """
979
        import warnings
×
980

981
        warnings.warn(
×
982
            "addGlobalFilter() is deprecated, use add_global_filter() instead",
983
            DeprecationWarning,
984
            stacklevel=2,
985
        )
986
        self.add_global_filter(filter)
×
987

988
    def add_global_filter(self, filter: BaseFilter) -> None:
1✔
989
        """
990
        Add a global filter to be applied to all fields.
991

992
        Args:
993
            filter: The filter to add.
994
        """
995
        self.global_filters.append(filter)
1✔
996

997
    def getGlobalFilters(self) -> List[BaseFilter]:
1✔
998
        """
999
        Retrieve all global filters associated with this InputFilter instance.
1000

1001
        This method returns a list of BaseFilter instances that have been
1002
        added as global filters. These filters are applied universally to
1003
        all fields during data processing.
1004

1005
        Returns:
1006
            List[BaseFilter]: A list of global filters.
1007
        """
1008
        import warnings
×
1009

1010
        warnings.warn(
×
1011
            "getGlobalFilters() is deprecated, use "
1012
            "get_global_filters() instead",
1013
            DeprecationWarning,
1014
            stacklevel=2,
1015
        )
1016
        return self.get_global_filters()
×
1017

1018
    def get_global_filters(self) -> List[BaseFilter]:
1✔
1019
        """
1020
        Retrieve all global filters associated with this InputFilter instance.
1021

1022
        This method returns a list of BaseFilter instances that have been
1023
        added as global filters. These filters are applied universally to
1024
        all fields during data processing.
1025

1026
        Returns:
1027
            List[BaseFilter]: A list of global filters.
1028
        """
1029
        return self.global_filters
1✔
1030

1031
    def clear(self) -> None:
1✔
1032
        """
1033
        Resets all fields of the InputFilter instance to their initial empty
1034
        state.
1035

1036
        This method clears the internal storage of fields, conditions, filters,
1037
        validators, and data, effectively resetting the object as if it were
1038
        newly initialized.
1039
        """
1040
        self.fields.clear()
1✔
1041
        self.conditions.clear()
1✔
1042
        self.global_filters.clear()
1✔
1043
        self.global_validators.clear()
1✔
1044
        self.data.clear()
1✔
1045
        self.validated_data.clear()
1✔
1046
        self.errors.clear()
1✔
1047

1048
    def merge(self, other: "InputFilter") -> None:
1✔
1049
        """
1050
        Merges another InputFilter instance intelligently into the current
1051
        instance.
1052

1053
        - Fields with the same name are merged recursively if possible,
1054
            otherwise overwritten.
1055
        - Conditions, are combined and duplicated.
1056
        - Global filters and validators are merged without duplicates.
1057

1058
        Args:
1059
            other (InputFilter): The InputFilter instance to merge.
1060
        """
1061
        if not isinstance(other, InputFilter):
1✔
1062
            raise TypeError(
1✔
1063
                "Can only merge with another InputFilter instance."
1064
            )
1065

1066
        for key, new_field in other.getInputs().items():
1✔
1067
            self.fields[key] = new_field
1✔
1068

1069
        self.conditions += other.conditions
1✔
1070

1071
        for filter in other.global_filters:
1✔
1072
            existing_type_map = {
1✔
1073
                type(v): i for i, v in enumerate(self.global_filters)
1074
            }
1075
            if type(filter) in existing_type_map:
1✔
1076
                self.global_filters[existing_type_map[type(filter)]] = filter
1✔
1077
            else:
1078
                self.global_filters.append(filter)
1✔
1079

1080
        for validator in other.global_validators:
1✔
1081
            existing_type_map = {
1✔
1082
                type(v): i for i, v in enumerate(self.global_validators)
1083
            }
1084
            if type(validator) in existing_type_map:
1✔
1085
                self.global_validators[
1✔
1086
                    existing_type_map[type(validator)]
1087
                ] = validator
1088
            else:
1089
                self.global_validators.append(validator)
1✔
1090

1091
    def setModel(self, model_class: Type[T]) -> None:
1✔
1092
        """
1093
        Set the model class for serialization.
1094

1095
        Args:
1096
            model_class (Type[T]): The class to use for serialization.
1097
        """
1098
        import warnings
×
1099

1100
        warnings.warn(
×
1101
            "setModel() is deprecated, use set_model() instead",
1102
            DeprecationWarning,
1103
            stacklevel=2,
1104
        )
1105
        self.set_model(model_class)
×
1106

1107
    def set_model(self, model_class: Type[T]) -> None:
1✔
1108
        """
1109
        Set the model class for serialization.
1110

1111
        Args:
1112
            model_class (Type[T]): The class to use for serialization.
1113
        """
1114
        self.model_class = model_class
1✔
1115

1116
    def serialize(self) -> Union[Dict[str, Any], T]:
1✔
1117
        """
1118
        Serialize the validated data. If a model class is set, returns an
1119
        instance of that class, otherwise returns the raw validated data.
1120

1121
        Returns:
1122
            Union[Dict[str, Any], T]: The serialized data.
1123
        """
1124
        if self.model_class is None:
1✔
1125
            return self.validated_data
1✔
1126

1127
        return self.model_class(**self.validated_data)
1✔
1128

1129
    def addGlobalValidator(self, validator: BaseValidator) -> None:
1✔
1130
        """
1131
        Add a global validator to be applied to all fields.
1132

1133
        Args:
1134
            validator (BaseValidator): The validator to add.
1135
        """
1136
        import warnings
×
1137

1138
        warnings.warn(
×
1139
            "addGlobalValidator() is deprecated, use "
1140
            "add_global_validator() instead",
1141
            DeprecationWarning,
1142
            stacklevel=2,
1143
        )
1144
        self.add_global_validator(validator)
×
1145

1146
    def add_global_validator(self, validator: BaseValidator) -> None:
1✔
1147
        """
1148
        Add a global validator to be applied to all fields.
1149

1150
        Args:
1151
            validator (BaseValidator): The validator to add.
1152
        """
1153
        self.global_validators.append(validator)
1✔
1154

1155
    def getGlobalValidators(self) -> List[BaseValidator]:
1✔
1156
        """
1157
        Retrieve all global validators associated with this InputFilter
1158
        instance.
1159

1160
        This method returns a list of BaseValidator instances that have been
1161
        added as global validators. These validators are applied universally
1162
        to all fields during validation.
1163

1164
        Returns:
1165
            List[BaseValidator]: A list of global validators.
1166
        """
1167
        import warnings
×
1168

1169
        warnings.warn(
×
1170
            "getGlobalValidators() is deprecated, use "
1171
            "get_global_validators() instead",
1172
            DeprecationWarning,
1173
            stacklevel=2,
1174
        )
1175
        return self.get_global_validators()
×
1176

1177
    def get_global_validators(self) -> List[BaseValidator]:
1✔
1178
        """
1179
        Retrieve all global validators associated with this InputFilter
1180
        instance.
1181

1182
        This method returns a list of BaseValidator instances that have been
1183
        added as global validators. These validators are applied universally
1184
        to all fields during validation.
1185

1186
        Returns:
1187
            List[BaseValidator]: A list of global validators.
1188
        """
1189
        return self.global_validators
1✔
STATUS · Troubleshooting · Open an Issue · Sales · Support · CAREERS · ENTERPRISE · START FREE · SCHEDULE DEMO
ANNOUNCEMENTS · TWITTER · TOS & SLA · Supported CI Services · What's a CI service? · Automated Testing

© 2026 Coveralls, Inc