Skip to content

Commit a0e84fd

Browse files
committed
Doc
1 parent eac3a46 commit a0e84fd

File tree

2 files changed

+199
-0
lines changed

2 files changed

+199
-0
lines changed

PLAN.md

Lines changed: 141 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,141 @@
1+
# Decorator-Based API Implementation Plan
2+
3+
## Ziel
4+
Implementierung einer decorator-basierten API für flask-inputfilter, die vollständig rückwärtskompatibel zur bestehenden imperativen API ist und beide Ansätze in einer Klasse kombinierbar macht.
5+
6+
## Vorher/Nachher Vergleich
7+
8+
### Aktuell (Imperativ)
9+
```python
10+
class UserInputFilter(InputFilter):
11+
def __init__(self):
12+
super().__init__()
13+
self.add('name', required=True, validators=[IsStringValidator()])
14+
self.add('age', required=True, validators=[IsIntegerValidator()])
15+
self.add('email', required=True, validators=[IsStringValidator()])
16+
```
17+
18+
### Neu (Deklarativ + Gemischt)
19+
```python
20+
class UserInputFilter(InputFilter):
21+
# Decorator-basierte Felder
22+
name: str = field(required=True, validators=[IsStringValidator()])
23+
age: int = field(required=True, validators=[IsIntegerValidator()])
24+
25+
# Global Validators/Filters
26+
_global_validators = [SomeGlobalValidator()]
27+
_global_filters = [StringTrimFilter()]
28+
29+
# Conditions
30+
_conditions = [ExactlyOneOfCondition(['phone', 'email'])]
31+
32+
# Weiterhin imperative API möglich
33+
def __init__(self):
34+
super().__init__()
35+
if self.needs_dynamic_field():
36+
self.add('dynamic_field', required=False)
37+
```
38+
39+
## Implementierungsschritte
40+
41+
### Phase 1: Descriptor-System
42+
- [ ] **FieldDescriptor** (`flask_inputfilter/decorators/field_descriptor.py`)
43+
- Hauptklasse für field() decorator
44+
- Unterstützt alle Parameter: required, default, fallback, filters, validators, steps, external_api, copy
45+
46+
- [ ] **ConditionDescriptor** (`flask_inputfilter/decorators/condition_descriptor.py`)
47+
- Für Conditions auf Klassenebene
48+
49+
- [ ] **GlobalValidatorDescriptor** (`flask_inputfilter/decorators/global_validator_descriptor.py`)
50+
- Für `_global_validators` Klassen-Attribut
51+
52+
- [ ] **GlobalFilterDescriptor** (`flask_inputfilter/decorators/global_filter_descriptor.py`)
53+
- Für `_global_filters` Klassen-Attribut
54+
55+
### Phase 2: Factory Functions
56+
- [ ] **Factory-Funktionen** (`flask_inputfilter/decorators/__init__.py`)
57+
```python
58+
def field(**kwargs) -> FieldDescriptor
59+
def condition(cond) -> ConditionDescriptor
60+
def global_validator(validator) -> GlobalValidatorDescriptor
61+
def global_filter(filter) -> GlobalFilterDescriptor
62+
```
63+
64+
### Phase 3: Metaclass
65+
- [ ] **InputFilterMeta** (`flask_inputfilter/meta.py`)
66+
- Scannt Klassen-Attribute nach Descriptors
67+
- Sammelt `_conditions`, `_global_validators`, `_global_filters`
68+
- Registriert sie in der Klasse für später
69+
70+
### Phase 4: InputFilter Integration
71+
- [ ] **InputFilter erweitern** (`flask_inputfilter/input_filter.py`)
72+
- Erbt von LegacyMethodsMixin + existierender Funktionalität
73+
- Nutzt InputFilterMeta als Metaclass
74+
- `_register_decorator_fields()` Methode für automatische Registration
75+
76+
### Phase 5: Testing
77+
- [ ] **Umfangreiche Test-Suite**
78+
- Positive Tests für alle Decorator-Features
79+
- Negative Tests für Fehlerfälle
80+
- Mixed API Tests (decorator + imperativ)
81+
- Inheritance Tests
82+
- Performance Tests
83+
- Flask Integration Tests
84+
- Edge Cases
85+
86+
### Phase 6: Dokumentation
87+
- [ ] **API Dokumentation aktualisieren**
88+
- [ ] **Migration Guide erstellen**
89+
- [ ] **Beispiele erweitern**
90+
91+
## Technische Details
92+
93+
### Dateistruktur
94+
```
95+
flask_inputfilter/
96+
├── mixins/
97+
│ ├── __init__.py
98+
│ ├── legacy_methods_mixin.py # add_*, replace, remove
99+
│ └── data_mixin.py # existierend
100+
├── decorators/
101+
│ ├── __init__.py # Factory-Funktionen
102+
│ ├── field_descriptor.py
103+
│ ├── condition_descriptor.py
104+
│ ├── global_validator_descriptor.py
105+
│ └── global_filter_descriptor.py
106+
├── meta.py # InputFilterMeta
107+
└── input_filter.py # Erweiterte Hauptklasse
108+
109+
tests/
110+
├── test_decorator_input_filter.py # Haupt-Tests
111+
├── test_descriptors.py # Descriptor-Tests
112+
├── test_mixed_api.py # Mixed API Tests
113+
└── test_performance.py # Performance-Vergleiche
114+
```
115+
116+
### Kompatibilität
117+
- **100% Rückwärtskompatibel**: Alle existierenden InputFilter funktionieren unverändert
118+
- **Gradueller Übergang**: Felder können schrittweise von imperativ zu deklarativ migriert werden
119+
- **Type Safety**: Type Hints bleiben erhalten und werden von IDEs unterstützt
120+
121+
### Testabdeckung Ziele
122+
- **>95% Code Coverage** für alle neuen Komponenten
123+
- **Negative Tests** für alle Fehlerszenarien
124+
- **Integration Tests** mit Flask
125+
- **Performance Benchmarks** vs. imperative API
126+
- **Memory Usage Tests** für Descriptor-Overhead
127+
128+
## Erfolgskriterien
129+
1. ✅ Alle existierenden Tests laufen weiterhin durch
130+
2. ✅ Neue decorator-basierte API funktioniert vollständig
131+
3. ✅ Mixed API (decorator + imperativ) funktioniert korrekt
132+
4. ✅ Type Hints funktionieren in IDEs
133+
5. ✅ Performance-Impact <5% gegenüber imperativer API
134+
6. ✅ Test Coverage >95% für neue Features
135+
7. ✅ Dokumentation und Beispiele sind vollständig
136+
137+
## Risiken & Mitigation
138+
- **Metaclass-Konflikte**: Sorgfältige Tests mit anderen Libraries
139+
- **Performance-Impact**: Benchmarking und Optimierung
140+
- **Type System Konflikte**: Tests mit mypy/pylint
141+
- **Breaking Changes**: Extensive Backward-Compatibility Tests

Update.md

Lines changed: 58 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,58 @@
1+
1. Add py.typed marker for better IDE support
2+
3+
- Create a py.typed file to indicate the package is type-annotated
4+
- This enables better autocomplete and type checking in IDEs
5+
6+
2. Simplify filter/validator imports
7+
8+
- Create convenience imports in init.py files
9+
- Add an "all" import pattern for common components
10+
- Example: from flask_inputfilter import filters, validators
11+
12+
3. Add builder pattern for InputFilter creation
13+
14+
- Implement fluent API for chaining field additions
15+
- Example: filter.field('name').required().string().min(3).max(50)
16+
17+
4. Create decorator-based field definition
18+
19+
- Allow defining fields using decorators on class attributes
20+
- More Pythonic and reduces boilerplate
21+
22+
5. Add common validation presets
23+
24+
- Email, URL, phone number, credit card validators
25+
- Common field combinations (e.g., address, user profile)
26+
27+
6. Improve error messages
28+
29+
- Add field path in nested validations
30+
- Support for i18n/localization
31+
- Better error aggregation for multiple fields
32+
33+
7. Add async support
34+
35+
- Support async validators for external API calls
36+
- Async filter application for IO-bound operations
37+
38+
8. Create CLI tool for code generation
39+
40+
- Generate InputFilter classes from JSON schema
41+
- Generate from OpenAPI specifications
42+
- Interactive filter builder
43+
44+
9. Add middleware integration helpers
45+
46+
- Direct integration with Flask-RESTful
47+
- Support for Flask-RESTX/Flask-Smorest
48+
- Marshmallow compatibility layer
49+
50+
10. Improve documentation
51+
52+
- Add more real-world examples
53+
- Create a cookbook section
54+
- Add migration guide from other validation libraries
55+
56+
57+
Validatoren erhalten richtige Fehler-Typen von Fehlern,
58+
die auftreten, damit man pro Fehlertyp eine Fehlermeldung schreiben kann

0 commit comments

Comments
 (0)