Skip to content

Commit 57573fd

Browse files
committed
Merge pull request #9 from LeanderCS/8
8 | Extend docs
2 parents 0083fcb + bd0b6df commit 57573fd

File tree

101 files changed

+1058
-364
lines changed

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

101 files changed

+1058
-364
lines changed

.DS_Store

8 KB
Binary file not shown.

.coveragerc

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,5 @@
11
[run]
2-
omit = __init__.py, setup.py, test_*.py
2+
source = flask_inputfilter
3+
4+
[report]
5+
omit = __init__.py, setup.py, */test/*

.dockerignore

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,5 @@
11
**.md
22
.gitignore
3-
.git
43
.github
54
.idea
65
.vscode

.github/workflows/test.yaml

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,6 @@
11
name: Run Tests
22

3-
on: [ push ]
3+
on: [push]
44

55
permissions:
66
actions: read
@@ -23,7 +23,12 @@ jobs:
2323
set -e # Exit immediately if a command exits with a non-zero status.
2424
set -u # Exit immediately if a variable is not defined.
2525
26-
docker run flask-inputfilter pytest
26+
docker run flask-inputfilter coverage run --source=flask_inputfilter -m pytest test/
27+
28+
- name: Upload coverage to Coveralls
29+
env:
30+
COVERALLS_REPO_TOKEN: ${{ secrets.COVERALLS_REPO_TOKEN }}
31+
run: docker run -e COVERALLS_REPO_TOKEN=${{ secrets.COVERALLS_REPO_TOKEN }} flask-inputfilter coveralls
2732

2833
- name: Run code style checks
2934
run: |

CHAGELOG.md

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,11 +18,11 @@ All notable changes to this project will be documented in this file.
1818

1919
### Added
2020

21-
- New condition functionality between fields. [Check it out](src/flask_inputfilter/Condition/README.md)
21+
- New condition functionality between fields. [Check it out](flask_inputfilter/Condition/README.md)
2222

2323
### Changed
2424

25-
- Switched external_api config from dict to class. [Check it out](src/flask_inputfilter/Model/ExternalApiConfig.py)
25+
- Switched external_api config from dict to class. [Check it out](flask_inputfilter/Model/ExternalApiConfig.py)
2626

2727

2828
## [0.0.4] - 2025-01-09

CREATE_OWN.md

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
# Create own

Dockerfile

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -2,7 +2,7 @@ FROM python:3.7-slim
22

33
WORKDIR /app
44

5-
RUN apt-get update && apt-get install -y gcc python3-dev
5+
RUN apt-get update && apt-get install -y gcc python3-dev git
66

77
RUN pip install --upgrade pip
88

README.md

Lines changed: 0 additions & 126 deletions
This file was deleted.

README.rst

Lines changed: 145 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,145 @@
1+
flask-inputfilter
2+
==================================
3+
4+
The `InputFilter` class is used to validate and filter input data in Flask applications.
5+
It provides a modular way to clean and ensure that incoming data meets expected format
6+
and type requirements before being processed.
7+
8+
:Test Status:
9+
10+
.. image:: https://img.shields.io/github/actions/workflow/status/LeanderCS/flask-inputfilter/test.yaml?branch=main&style=flat-square&label=Github%20Actions
11+
:target: https://github.com/LeanderCS/flask-inputfilter/actions
12+
.. image:: https://img.shields.io/coveralls/LeanderCS/flask-inputfilter/main.svg?style=flat-square&label=Coverage
13+
:target: https://coveralls.io/r/LeanderCS/flask-inputfilter
14+
15+
:Version Info:
16+
17+
.. image:: https://img.shields.io/pypi/v/flask-inputfilter?style=flat-square&label=PyPI
18+
:target: https://pypi.org/project/flask-inputfilter/
19+
20+
:Compatibility:
21+
22+
.. image:: https://img.shields.io/pypi/pyversions/flask-inputfilter?style=flat-square&label=PyPI
23+
:target: https://pypi.org/project/flask-inputfilter/
24+
25+
:Downloads:
26+
27+
.. image:: https://img.shields.io/pypi/dm/flask-inputfilter?style=flat-square&label=PyPI
28+
:target: https://pypi.org/project/flask-inputfilter/
29+
30+
Installation
31+
============
32+
33+
.. code-block:: bash
34+
35+
pip install flask-inputfilter
36+
37+
Quickstart
38+
==========
39+
40+
To use the `InputFilter` class, create a new class that inherits from it and define the
41+
fields you want to validate and filter.
42+
43+
There are numerous filters and validators available, but you can also create your own.
44+
Refer to the [CREATE_OWN.md](CREATE_OWN.md) file for guidance.
45+
46+
Definition
47+
----------
48+
49+
.. code-block:: python
50+
51+
from flask_inputfilter import InputFilter
52+
from flask_inputfilter.Condition import ExactlyOneOfCondition
53+
from flask_inputfilter.Enum import RegexEnum
54+
from flask_inputfilter.Filter import StringTrimFilter, ToIntegerFilter, ToNullFilter
55+
from flask_inputfilter.Validator import IsIntegerValidator, IsStringValidator, RegexValidator
56+
57+
class UpdateZipcodeInputFilter(InputFilter):
58+
def __init__(self):
59+
super().__init__()
60+
61+
self.add(
62+
'id',
63+
required=True,
64+
filters=[ToIntegerFilter(), ToNullFilter()],
65+
validators=[
66+
IsIntegerValidator()
67+
]
68+
)
69+
70+
self.add(
71+
'zipcode',
72+
filters=[StringTrimFilter()],
73+
validators=[
74+
RegexValidator(
75+
RegexEnum.POSTAL_CODE.value,
76+
'The zipcode is not in the correct format.'
77+
)
78+
]
79+
)
80+
81+
self.add(
82+
'city',
83+
filters=[StringTrimFilter()],
84+
validators=[
85+
IsStringValidator()
86+
]
87+
)
88+
89+
self.addCondition(
90+
ExactlyOneOfCondition(['zipcode', 'city'])
91+
)
92+
93+
Usage
94+
-----
95+
96+
To use the `InputFilter` class, call the `validate` method on the class instance.
97+
After calling `validate`, the validated data will be available in `g.validatedData`.
98+
If the data is invalid, a 400 response with an error message will be returned.
99+
100+
.. code-block:: python
101+
102+
from flask import Flask, g
103+
from your-path import UpdateZipcodeInputFilter
104+
105+
app = Flask(__name__)
106+
107+
@app.route('/update-zipcode', methods=['POST'])
108+
@UpdateZipcodeInputFilter.validate()
109+
def updateZipcode():
110+
data = g.validatedData
111+
112+
# Do something with validated data
113+
id = data.get('id')
114+
zipcode = data.get('zipcode')
115+
116+
Options
117+
=======
118+
119+
The `add` method supports several options:
120+
121+
- `Required`_
122+
- `Filter` (see `Filter` documentation in :file:`flask_inputfilter/Filter/README.md`)
123+
- `Validator` (see `Validator` documentation in :file:`flask_inputfilter/Validator/README.md`)
124+
- `Default`_
125+
- `Fallback`_
126+
- `ExternalApi` (see :file:`EXTERNAL_API.md`)
127+
128+
Required
129+
--------
130+
131+
The `required` option specifies whether the field must be included in the input data.
132+
If the field is missing, a `ValidationError` will be raised with an appropriate error message.
133+
134+
Default
135+
-------
136+
137+
The `default` option allows you to specify a default value to use if the field is not
138+
present in the input data.
139+
140+
Fallback
141+
--------
142+
143+
The `fallback` option specifies a value to use if validation fails or required data
144+
is missing. Note that if the field is optional and absent, `fallback` will not apply;
145+
use `default` in such cases.
Lines changed: 20 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,20 @@
1+
from typing import Any, Dict
2+
3+
from .BaseCondition import BaseCondition
4+
5+
6+
class ArrayLengthEqualCondition(BaseCondition):
7+
"""
8+
Condition that checks if the array is of the specified length.
9+
"""
10+
11+
def __init__(
12+
self, first_array_field: str, second_array_field: str
13+
) -> None:
14+
self.first_array_field = first_array_field
15+
self.second_array_field = second_array_field
16+
17+
def check(self, data: Dict[str, Any]) -> bool:
18+
return len(data.get(self.first_array_field) or []) == len(
19+
data.get(self.second_array_field) or []
20+
)

0 commit comments

Comments
 (0)