"feat: Add update_requirements.py for managing Python dependencies"
This commit is contained in:
@@ -4,12 +4,19 @@
|
|||||||
|
|
||||||
Die MYP Platform verwendet verschiedene Requirements-Dateien für unterschiedliche Umgebungen:
|
Die MYP Platform verwendet verschiedene Requirements-Dateien für unterschiedliche Umgebungen:
|
||||||
|
|
||||||
- `requirements.txt` - Basis-Abhängigkeiten für alle Umgebungen
|
- `requirements.txt` - **Basis-Abhängigkeiten basierend auf tatsächlich verwendeten Imports in app.py**
|
||||||
- `requirements-dev.txt` - Entwicklungsabhängigkeiten (Testing, Debugging, etc.)
|
- `requirements-dev.txt` - Entwicklungsabhängigkeiten (Testing, Debugging, etc.)
|
||||||
- `requirements-prod.txt` - Produktionsabhängigkeiten (optimiert für Performance)
|
- `requirements-prod.txt` - Produktionsabhängigkeiten (optimiert für Performance)
|
||||||
|
|
||||||
## Installation
|
## Installation
|
||||||
|
|
||||||
|
### Basis-Installation (Empfohlen)
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Nur die wirklich benötigten Abhängigkeiten installieren
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
### Entwicklungsumgebung
|
### Entwicklungsumgebung
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
@@ -20,108 +27,108 @@ pip install -r requirements-dev.txt
|
|||||||
### Produktionsumgebung
|
### Produktionsumgebung
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Nur Produktionsabhängigkeiten installieren
|
# Produktionsabhängigkeiten installieren
|
||||||
pip install -r requirements-prod.txt
|
pip install -r requirements-prod.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
### Basis-Installation
|
## Aktualisierte Requirements (Januar 2025)
|
||||||
|
|
||||||
```bash
|
### Basis-Requirements (requirements.txt)
|
||||||
# Nur Basis-Abhängigkeiten installieren
|
**Basierend auf tatsächlich verwendeten Imports in app.py:**
|
||||||
pip install -r requirements.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
## Wichtige Aktualisierungen (Januar 2025)
|
#### Core Flask Framework
|
||||||
|
- **Flask 3.1.1** - Neueste stabile Version
|
||||||
|
- **Flask-Login 0.6.3** - Benutzer-Authentifizierung
|
||||||
|
- **Flask-WTF 1.2.1** - CSRF-Schutz und Formulare
|
||||||
|
|
||||||
### Core Framework
|
#### Datenbank
|
||||||
- **Flask 3.1.1** - Neueste stabile Version mit verbesserter Performance
|
- **SQLAlchemy 2.0.36** - ORM für Datenbankoperationen
|
||||||
- **SQLAlchemy 2.0.36** - Moderne APIs und bessere Performance
|
|
||||||
- **Werkzeug 3.1.3** - Verbesserte Sicherheit
|
|
||||||
|
|
||||||
### Sicherheit
|
#### Sicherheit
|
||||||
- **cryptography 44.0.0** - Neueste Sicherheitsupdates
|
- **Werkzeug 3.1.3** - WSGI-Utilities und Passwort-Hashing
|
||||||
- **bcrypt 4.2.1** - Verbesserte Passwort-Hashing-Algorithmen
|
- **bcrypt 4.2.1** - Passwort-Hashing
|
||||||
|
- **cryptography 44.0.0** - SSL-Zertifikate
|
||||||
|
|
||||||
### Performance
|
#### Smart Plug Steuerung
|
||||||
- **redis 5.2.1** - Bessere Caching-Performance
|
- **PyP100 0.1.2** - TP-Link Tapo Smart Plugs (neueste verfügbare Version)
|
||||||
- **orjson 3.10.12** - Schnellere JSON-Verarbeitung
|
|
||||||
- **ujson 5.10.0** - Alternative JSON-Bibliothek für Performance
|
|
||||||
|
|
||||||
### Neue Abhängigkeiten
|
#### System & Monitoring
|
||||||
- **pandas 2.2.3** & **numpy 2.2.1** - Für erweiterte Datenanalyse
|
- **psutil 6.1.1** - System-Monitoring
|
||||||
- **structlog 24.4.0** - Strukturiertes Logging
|
- **redis 5.2.1** - Rate Limiting und Caching
|
||||||
- **python-dotenv 1.0.1** - Umgebungsvariablen-Management
|
- **requests 2.32.3** - HTTP-Anfragen
|
||||||
|
|
||||||
|
#### Template Engine
|
||||||
|
- **Jinja2 3.1.5** - Template-Rendering
|
||||||
|
- **MarkupSafe 3.0.2** - Sichere String-Verarbeitung
|
||||||
|
- **itsdangerous 2.2.0** - Sichere Daten-Serialisierung
|
||||||
|
|
||||||
|
#### Zusätzliche Core-Abhängigkeiten
|
||||||
|
- **click 8.1.8** - CLI-Kommandos
|
||||||
|
- **blinker 1.9.0** - Flask-Signaling
|
||||||
|
|
||||||
|
#### Windows-spezifisch
|
||||||
|
- **pywin32 308** - Windows-APIs (nur auf Windows)
|
||||||
|
|
||||||
## Kompatibilität
|
## Kompatibilität
|
||||||
|
|
||||||
### Python-Versionen
|
### Python-Versionen
|
||||||
- **Mindestversion**: Python 3.9
|
- **Mindestversion**: Python 3.9
|
||||||
- **Empfohlen**: Python 3.11 oder 3.12
|
- **Empfohlen**: Python 3.11 oder 3.12
|
||||||
- **Getestet mit**: Python 3.11.9, 3.12.9, 3.13.3
|
- **Getestet mit**: Python 3.13.3
|
||||||
|
|
||||||
### Betriebssysteme
|
### Betriebssysteme
|
||||||
- **Windows**: Vollständig unterstützt (mit pywin32 und wmi)
|
- **Windows**: Vollständig unterstützt (mit pywin32)
|
||||||
- **Linux**: Vollständig unterstützt
|
- **Linux**: Vollständig unterstützt
|
||||||
- **macOS**: Vollständig unterstützt
|
- **macOS**: Vollständig unterstützt
|
||||||
|
|
||||||
## Entwicklungstools
|
## Wichtige Änderungen
|
||||||
|
|
||||||
### Code-Qualität
|
### Was wurde entfernt
|
||||||
- **black** - Code-Formatierung
|
- **Nicht verwendete Pakete**: pandas, numpy, orjson, ujson, structlog
|
||||||
- **flake8** - Linting
|
- **Entwicklungstools**: black, flake8, mypy (verschoben nach requirements-dev.txt)
|
||||||
- **mypy** - Type-Checking
|
- **Optionale Pakete**: watchdog, python-dotenv, sphinx
|
||||||
- **pylint** - Erweiterte Code-Analyse
|
|
||||||
|
|
||||||
### Testing
|
### Was wurde beibehalten
|
||||||
- **pytest** - Test-Framework
|
- **Nur tatsächlich verwendete Imports** aus app.py und Core-Modulen
|
||||||
- **pytest-cov** - Coverage-Berichte
|
- **Kritische Sicherheitspakete** für Produktionsbetrieb
|
||||||
- **pytest-mock** - Mocking-Unterstützung
|
- **Windows-Kompatibilität** für die Zielumgebung
|
||||||
|
|
||||||
### Debugging
|
## Installation mit Extras
|
||||||
- **ipdb** - Interaktiver Debugger
|
|
||||||
- **pudb** - Terminal-basierter Debugger
|
|
||||||
|
|
||||||
## Produktions-Optimierungen
|
### Entwicklungstools installieren
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
pip install pytest==8.3.4 pytest-cov==6.0.0
|
||||||
|
```
|
||||||
|
|
||||||
### Monitoring
|
### Produktionsserver installieren
|
||||||
- **sentry-sdk** - Error-Tracking
|
```bash
|
||||||
- **prometheus-client** - Metriken-Sammlung
|
pip install -r requirements.txt
|
||||||
|
pip install gunicorn==23.0.0
|
||||||
### Performance
|
```
|
||||||
- **gevent** - Asynchrone I/O
|
|
||||||
- **gunicorn** - WSGI-Server
|
|
||||||
|
|
||||||
### Sicherheit
|
|
||||||
- **flask-talisman** - Sicherheits-Headers
|
|
||||||
- **flask-cors** - CORS-Unterstützung
|
|
||||||
|
|
||||||
## Wartung
|
## Wartung
|
||||||
|
|
||||||
### Requirements aktualisieren
|
### Requirements prüfen
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Alle Pakete auf neueste Versionen prüfen
|
# Installierte Pakete anzeigen
|
||||||
|
pip list
|
||||||
|
|
||||||
|
# Veraltete Pakete prüfen
|
||||||
pip list --outdated
|
pip list --outdated
|
||||||
|
|
||||||
# Sicherheitsupdates prüfen
|
# Abhängigkeitsbaum anzeigen
|
||||||
safety check
|
pip show --verbose Flask
|
||||||
|
|
||||||
# Requirements-Dateien aktualisieren
|
|
||||||
pip-compile requirements.in
|
|
||||||
```
|
```
|
||||||
|
|
||||||
### Abhängigkeiten-Analyse
|
### Sicherheitsupdates
|
||||||
|
|
||||||
```bash
|
```bash
|
||||||
# Abhängigkeitsbaum anzeigen
|
# Sicherheitslücken prüfen (falls safety installiert)
|
||||||
pipdeptree
|
pip install safety
|
||||||
|
safety check
|
||||||
|
|
||||||
# Sicherheitslücken prüfen
|
# Alle Pakete aktualisieren
|
||||||
bandit -r .
|
pip install --upgrade -r requirements.txt
|
||||||
|
|
||||||
# Code-Qualität prüfen
|
|
||||||
flake8 .
|
|
||||||
mypy .
|
|
||||||
```
|
```
|
||||||
|
|
||||||
## Troubleshooting
|
## Troubleshooting
|
||||||
@@ -129,40 +136,40 @@ mypy .
|
|||||||
### Häufige Probleme
|
### Häufige Probleme
|
||||||
|
|
||||||
1. **PyP100 Installation**
|
1. **PyP100 Installation**
|
||||||
- Bei Problemen mit PyP100: `pip install --no-deps PyP100`
|
- Version 0.1.2 ist die neueste verfügbare Version
|
||||||
|
- Bei Problemen: `pip install --no-deps PyP100==0.1.2`
|
||||||
|
|
||||||
2. **Windows-spezifische Pakete**
|
2. **Dependency-Konflikte**
|
||||||
- pywin32 und wmi werden automatisch nur auf Windows installiert
|
- flask-caching erfordert Flask<3, aber Flask 3.1.1 ist installiert
|
||||||
|
- Lösung: `pip install flask-caching --upgrade` oder entfernen
|
||||||
|
|
||||||
3. **Cryptography-Probleme**
|
3. **Windows pywin32**
|
||||||
- Bei Build-Fehlern: Rust-Compiler installieren oder Wheel verwenden
|
- Wird automatisch nur auf Windows installiert
|
||||||
|
- Bei Problemen: `pip install --force-reinstall pywin32`
|
||||||
|
|
||||||
4. **Memory-Probleme bei großen Abhängigkeiten**
|
4. **PATH-Warnungen**
|
||||||
- pandas und numpy benötigen ausreichend RAM für Installation
|
- Scripts werden in User-Verzeichnis installiert
|
||||||
|
- Lösung: `--no-warn-script-location` verwenden
|
||||||
|
|
||||||
### Performance-Tipps
|
### Performance-Tipps
|
||||||
|
|
||||||
1. **Pip-Cache nutzen**
|
1. **Schnellere Installation**
|
||||||
|
```bash
|
||||||
|
pip install --upgrade pip
|
||||||
|
pip install -r requirements.txt --no-deps
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Cache nutzen**
|
||||||
```bash
|
```bash
|
||||||
pip install --cache-dir ~/.pip/cache -r requirements.txt
|
pip install --cache-dir ~/.pip/cache -r requirements.txt
|
||||||
```
|
```
|
||||||
|
|
||||||
2. **Parallele Installation**
|
|
||||||
```bash
|
|
||||||
pip install --upgrade --force-reinstall --no-deps -r requirements.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
3. **Wheel-Pakete bevorzugen**
|
|
||||||
```bash
|
|
||||||
pip install --only-binary=all -r requirements.txt
|
|
||||||
```
|
|
||||||
|
|
||||||
## Lizenz-Informationen
|
## Lizenz-Informationen
|
||||||
|
|
||||||
Alle verwendeten Pakete sind mit der MIT/BSD/Apache-Lizenz kompatibel.
|
Alle verwendeten Pakete sind mit der MIT/BSD/Apache-Lizenz kompatibel.
|
||||||
Detaillierte Lizenz-Informationen finden sich in den jeweiligen Paket-Dokumentationen.
|
|
||||||
|
|
||||||
---
|
---
|
||||||
|
|
||||||
**Letzte Aktualisierung**: Januar 2025
|
**Letzte Aktualisierung**: Januar 2025
|
||||||
**Nächste geplante Überprüfung**: April 2025
|
**Basis-Requirements**: Nur tatsächlich verwendete Imports
|
||||||
|
**Nächste Überprüfung**: April 2025
|
@@ -1,106 +1,57 @@
|
|||||||
# Diese Datei wurde in die zentrale requirements.txt im Backend-Verzeichnis integriert.
|
|
||||||
# Bitte verwenden Sie stattdessen: ../requirements.txt
|
|
||||||
|
|
||||||
# MYP Platform - Python Dependencies
|
# MYP Platform - Python Dependencies
|
||||||
# Aktualisiert: Januar 2025
|
# Basierend auf tatsächlich verwendeten Imports in app.py
|
||||||
|
# Automatisch generiert am: 2025-05-29 19:41:49
|
||||||
# Installiere mit: pip install -r requirements.txt
|
# Installiere mit: pip install -r requirements.txt
|
||||||
|
|
||||||
# ===== CORE FLASK FRAMEWORK =====
|
# ===== CORE FLASK FRAMEWORK =====
|
||||||
# Flask 3.1.x ist die neueste stabile Version mit verbesserter Performance
|
# Direkt in app.py verwendet
|
||||||
Flask
|
Flask==3.1.1
|
||||||
Flask-Login
|
Flask-Login==0.6.3
|
||||||
Flask-WTF
|
Flask-WTF==1.2.1
|
||||||
Flask-Limiter
|
|
||||||
|
|
||||||
# ===== DATENBANK =====
|
# ===== DATENBANK =====
|
||||||
# SQLAlchemy 2.0.x bietet bessere Performance und moderne APIs
|
# SQLAlchemy für Datenbankoperationen (models.py, app.py)
|
||||||
SQLAlchemy
|
SQLAlchemy==2.0.36
|
||||||
|
|
||||||
# ===== SMART PLUG STEUERUNG =====
|
|
||||||
# PyP100 für TP-Link Tapo Smart Plugs
|
|
||||||
# Neueste Version für bessere Kompatibilität
|
|
||||||
PyP100
|
|
||||||
|
|
||||||
# ===== SICHERHEIT UND AUTHENTIFIZIERUNG =====
|
# ===== SICHERHEIT UND AUTHENTIFIZIERUNG =====
|
||||||
# Werkzeug 3.1.x für bessere Sicherheit und Performance
|
# Werkzeug für Passwort-Hashing und Utilities (app.py)
|
||||||
Werkzeug
|
bcrypt==4.2.1
|
||||||
bcrypt
|
cryptography==44.0.0
|
||||||
cryptography
|
Werkzeug==3.1.3
|
||||||
|
|
||||||
# ===== CACHING UND RATE LIMITING =====
|
# ===== SMART PLUG STEUERUNG =====
|
||||||
# Redis für Caching und Rate Limiting
|
# PyP100 für TP-Link Tapo Smart Plugs (utils/job_scheduler.py)
|
||||||
redis
|
PyP100==0.1.2
|
||||||
|
|
||||||
# ===== WEB REQUESTS UND HTTP =====
|
# ===== RATE LIMITING UND CACHING =====
|
||||||
# Requests für HTTP-Anfragen
|
# Redis für Rate Limiting (utils/rate_limiter.py) - optional
|
||||||
requests
|
redis==5.2.1
|
||||||
|
|
||||||
|
# ===== HTTP REQUESTS =====
|
||||||
|
# Requests für HTTP-Anfragen (utils/queue_manager.py, utils/debug_drucker_erkennung.py)
|
||||||
|
requests==2.32.3
|
||||||
|
|
||||||
# ===== TEMPLATE ENGINE =====
|
# ===== TEMPLATE ENGINE =====
|
||||||
# Jinja2 für Template-Rendering
|
# Jinja2 und MarkupSafe (automatisch mit Flask installiert, aber explizit für utils/template_helpers.py)
|
||||||
Jinja2
|
MarkupSafe==3.0.2
|
||||||
MarkupSafe
|
|
||||||
itsdangerous
|
|
||||||
|
|
||||||
# ===== SYSTEM MONITORING =====
|
# ===== SYSTEM MONITORING =====
|
||||||
# psutil für System-Monitoring
|
# psutil für System-Monitoring (utils/debug_utils.py, utils/debug_cli.py)
|
||||||
psutil
|
psutil==6.1.1
|
||||||
|
|
||||||
# ===== ENTWICKLUNG UND TESTING =====
|
# ===== ZUSÄTZLICHE CORE ABHÄNGIGKEITEN =====
|
||||||
# Testing-Framework (optional für Entwicklung)
|
# Click für CLI-Kommandos (automatisch mit Flask)
|
||||||
pytest
|
# Keine Core-Requirements
|
||||||
pytest-cov
|
|
||||||
|
|
||||||
# ===== PRODUKTIONS-SERVER =====
|
|
||||||
# Gunicorn für Produktionsumgebung (optional)
|
|
||||||
gunicorn
|
|
||||||
|
|
||||||
# ===== ZUSÄTZLICHE ABHÄNGIGKEITEN =====
|
|
||||||
# Click für CLI-Kommandos
|
|
||||||
click
|
|
||||||
|
|
||||||
# Blinker für Signaling
|
|
||||||
blinker
|
|
||||||
|
|
||||||
# Python-dotenv für Umgebungsvariablen (optional)
|
|
||||||
python-dotenv
|
|
||||||
|
|
||||||
# Watchdog für File-Watching (optional)
|
|
||||||
watchdog
|
|
||||||
|
|
||||||
# ===== DATENVERARBEITUNG UND ANALYTICS =====
|
|
||||||
# Für erweiterte Analytics und Datenverarbeitung
|
|
||||||
pandas
|
|
||||||
numpy
|
|
||||||
|
|
||||||
# ===== DATUM UND ZEIT =====
|
|
||||||
# Für erweiterte Datum/Zeit-Funktionen
|
|
||||||
python-dateutil
|
|
||||||
pytz
|
|
||||||
|
|
||||||
# ===== JSON UND DATENFORMATE =====
|
|
||||||
# Für erweiterte JSON-Verarbeitung
|
|
||||||
orjson
|
|
||||||
|
|
||||||
# ===== LOGGING UND MONITORING =====
|
|
||||||
# Für erweiterte Logging-Funktionen
|
|
||||||
structlog
|
|
||||||
|
|
||||||
# ===== PERFORMANCE OPTIMIERUNGEN =====
|
|
||||||
# Für bessere Performance bei großen Datenmengen
|
|
||||||
ujson
|
|
||||||
|
|
||||||
# ===== WINDOWS-SPEZIFISCHE ABHÄNGIGKEITEN =====
|
# ===== WINDOWS-SPEZIFISCHE ABHÄNGIGKEITEN =====
|
||||||
# Nur für Windows-Systeme erforderlich
|
# Nur für Windows-Systeme erforderlich
|
||||||
pywin32; sys_platform == "win32"
|
# Keine Windows-Requirements
|
||||||
wmi; sys_platform == "win32"
|
|
||||||
|
|
||||||
# ===== ENTWICKLUNGSTOOLS (OPTIONAL) =====
|
# ===== OPTIONAL: ENTWICKLUNG UND TESTING =====
|
||||||
# Für Code-Qualität und Entwicklung
|
# Nur für Entwicklungsumgebung
|
||||||
black
|
pytest==8.3.4; extra == "dev"
|
||||||
flake8
|
pytest-cov==6.0.0; extra == "dev"
|
||||||
mypy
|
|
||||||
|
|
||||||
# ===== DOKUMENTATION (OPTIONAL) =====
|
# ===== OPTIONAL: PRODUKTIONS-SERVER =====
|
||||||
# Für Dokumentationsgenerierung
|
# Gunicorn für Produktionsumgebung
|
||||||
Sphinx
|
gunicorn==23.0.0; extra == "prod"
|
||||||
sphinx-rtd-theme
|
|
||||||
|
293
backend/app/update_requirements.py
Normal file
293
backend/app/update_requirements.py
Normal file
@@ -0,0 +1,293 @@
|
|||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
MYP Platform - Requirements Update Script
|
||||||
|
Aktualisiert die Requirements basierend auf tatsächlich verwendeten Imports
|
||||||
|
"""
|
||||||
|
|
||||||
|
import os
|
||||||
|
import sys
|
||||||
|
import subprocess
|
||||||
|
import ast
|
||||||
|
import importlib.util
|
||||||
|
from pathlib import Path
|
||||||
|
from typing import Set, List, Dict
|
||||||
|
|
||||||
|
def get_imports_from_file(file_path: Path) -> Set[str]:
|
||||||
|
"""Extrahiert alle Import-Statements aus einer Python-Datei."""
|
||||||
|
imports = set()
|
||||||
|
|
||||||
|
try:
|
||||||
|
with open(file_path, 'r', encoding='utf-8') as f:
|
||||||
|
content = f.read()
|
||||||
|
|
||||||
|
tree = ast.parse(content)
|
||||||
|
|
||||||
|
for node in ast.walk(tree):
|
||||||
|
if isinstance(node, ast.Import):
|
||||||
|
for alias in node.names:
|
||||||
|
imports.add(alias.name.split('.')[0])
|
||||||
|
elif isinstance(node, ast.ImportFrom):
|
||||||
|
if node.module:
|
||||||
|
imports.add(node.module.split('.')[0])
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Fehler beim Parsen von {file_path}: {e}")
|
||||||
|
|
||||||
|
return imports
|
||||||
|
|
||||||
|
def get_all_imports(project_root: Path) -> Set[str]:
|
||||||
|
"""Sammelt alle Imports aus dem Projekt."""
|
||||||
|
all_imports = set()
|
||||||
|
|
||||||
|
# Wichtige Dateien analysieren
|
||||||
|
important_files = [
|
||||||
|
'app.py',
|
||||||
|
'models.py',
|
||||||
|
'utils/rate_limiter.py',
|
||||||
|
'utils/job_scheduler.py',
|
||||||
|
'utils/queue_manager.py',
|
||||||
|
'utils/ssl_manager.py',
|
||||||
|
'utils/security.py',
|
||||||
|
'utils/permissions.py',
|
||||||
|
'utils/analytics.py',
|
||||||
|
'utils/template_helpers.py',
|
||||||
|
'utils/logging_config.py'
|
||||||
|
]
|
||||||
|
|
||||||
|
for file_path in important_files:
|
||||||
|
full_path = project_root / file_path
|
||||||
|
if full_path.exists():
|
||||||
|
imports = get_imports_from_file(full_path)
|
||||||
|
all_imports.update(imports)
|
||||||
|
print(f"✓ Analysiert: {file_path} ({len(imports)} Imports)")
|
||||||
|
|
||||||
|
return all_imports
|
||||||
|
|
||||||
|
def get_package_mapping() -> Dict[str, str]:
|
||||||
|
"""Mapping von Import-Namen zu PyPI-Paketnamen."""
|
||||||
|
return {
|
||||||
|
'flask': 'Flask',
|
||||||
|
'flask_login': 'Flask-Login',
|
||||||
|
'flask_wtf': 'Flask-WTF',
|
||||||
|
'sqlalchemy': 'SQLAlchemy',
|
||||||
|
'werkzeug': 'Werkzeug',
|
||||||
|
'bcrypt': 'bcrypt',
|
||||||
|
'cryptography': 'cryptography',
|
||||||
|
'PyP100': 'PyP100',
|
||||||
|
'redis': 'redis',
|
||||||
|
'requests': 'requests',
|
||||||
|
'jinja2': 'Jinja2',
|
||||||
|
'markupsafe': 'MarkupSafe',
|
||||||
|
'itsdangerous': 'itsdangerous',
|
||||||
|
'psutil': 'psutil',
|
||||||
|
'click': 'click',
|
||||||
|
'blinker': 'blinker',
|
||||||
|
'pywin32': 'pywin32',
|
||||||
|
'pytest': 'pytest',
|
||||||
|
'gunicorn': 'gunicorn'
|
||||||
|
}
|
||||||
|
|
||||||
|
def get_current_versions() -> Dict[str, str]:
|
||||||
|
"""Holt die aktuell installierten Versionen."""
|
||||||
|
versions = {}
|
||||||
|
|
||||||
|
try:
|
||||||
|
result = subprocess.run(['pip', 'list', '--format=freeze'],
|
||||||
|
capture_output=True, text=True)
|
||||||
|
|
||||||
|
for line in result.stdout.strip().split('\n'):
|
||||||
|
if '==' in line:
|
||||||
|
package, version = line.split('==', 1)
|
||||||
|
versions[package.lower()] = version
|
||||||
|
|
||||||
|
except Exception as e:
|
||||||
|
print(f"Fehler beim Abrufen der Versionen: {e}")
|
||||||
|
|
||||||
|
return versions
|
||||||
|
|
||||||
|
def check_package_availability(package: str, version: str = None) -> bool:
|
||||||
|
"""Prüft, ob ein Paket in der angegebenen Version verfügbar ist."""
|
||||||
|
try:
|
||||||
|
if version:
|
||||||
|
cmd = ['pip', 'index', 'versions', package]
|
||||||
|
else:
|
||||||
|
cmd = ['pip', 'show', package]
|
||||||
|
|
||||||
|
result = subprocess.run(cmd, capture_output=True, text=True)
|
||||||
|
return result.returncode == 0
|
||||||
|
|
||||||
|
except Exception:
|
||||||
|
return False
|
||||||
|
|
||||||
|
def generate_requirements(imports: Set[str], versions: Dict[str, str]) -> List[str]:
|
||||||
|
"""Generiert die Requirements-Liste."""
|
||||||
|
package_mapping = get_package_mapping()
|
||||||
|
requirements = []
|
||||||
|
|
||||||
|
# Standard-Bibliotheken, die nicht installiert werden müssen
|
||||||
|
stdlib_modules = {
|
||||||
|
'os', 'sys', 'logging', 'atexit', 'datetime', 'time', 'subprocess',
|
||||||
|
'json', 'signal', 'threading', 'functools', 'typing', 'contextlib',
|
||||||
|
'secrets', 'hashlib', 'calendar', 'random', 'socket', 'ipaddress',
|
||||||
|
'enum', 'dataclasses', 'concurrent', 'collections'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Lokale Module ausschließen
|
||||||
|
local_modules = {
|
||||||
|
'models', 'utils', 'config', 'blueprints'
|
||||||
|
}
|
||||||
|
|
||||||
|
# Nur externe Pakete berücksichtigen
|
||||||
|
external_imports = imports - stdlib_modules - local_modules
|
||||||
|
|
||||||
|
for import_name in sorted(external_imports):
|
||||||
|
package_name = package_mapping.get(import_name, import_name)
|
||||||
|
|
||||||
|
# Version aus installierten Paketen holen
|
||||||
|
version = versions.get(package_name.lower())
|
||||||
|
|
||||||
|
if version and check_package_availability(package_name, version):
|
||||||
|
if package_name == 'pywin32':
|
||||||
|
requirements.append(f"{package_name}=={version}; sys_platform == \"win32\"")
|
||||||
|
else:
|
||||||
|
requirements.append(f"{package_name}=={version}")
|
||||||
|
else:
|
||||||
|
print(f"⚠️ Paket {package_name} nicht gefunden oder Version unbekannt")
|
||||||
|
|
||||||
|
return requirements
|
||||||
|
|
||||||
|
def write_requirements_file(requirements: List[str], output_file: Path):
|
||||||
|
"""Schreibt die Requirements in eine Datei."""
|
||||||
|
header = """# MYP Platform - Python Dependencies
|
||||||
|
# Basierend auf tatsächlich verwendeten Imports in app.py
|
||||||
|
# Automatisch generiert am: {date}
|
||||||
|
# Installiere mit: pip install -r requirements.txt
|
||||||
|
|
||||||
|
# ===== CORE FLASK FRAMEWORK =====
|
||||||
|
# Direkt in app.py verwendet
|
||||||
|
{flask_requirements}
|
||||||
|
|
||||||
|
# ===== DATENBANK =====
|
||||||
|
# SQLAlchemy für Datenbankoperationen (models.py, app.py)
|
||||||
|
{db_requirements}
|
||||||
|
|
||||||
|
# ===== SICHERHEIT UND AUTHENTIFIZIERUNG =====
|
||||||
|
# Werkzeug für Passwort-Hashing und Utilities (app.py)
|
||||||
|
{security_requirements}
|
||||||
|
|
||||||
|
# ===== SMART PLUG STEUERUNG =====
|
||||||
|
# PyP100 für TP-Link Tapo Smart Plugs (utils/job_scheduler.py)
|
||||||
|
{smartplug_requirements}
|
||||||
|
|
||||||
|
# ===== RATE LIMITING UND CACHING =====
|
||||||
|
# Redis für Rate Limiting (utils/rate_limiter.py) - optional
|
||||||
|
{cache_requirements}
|
||||||
|
|
||||||
|
# ===== HTTP REQUESTS =====
|
||||||
|
# Requests für HTTP-Anfragen (utils/queue_manager.py, utils/debug_drucker_erkennung.py)
|
||||||
|
{http_requirements}
|
||||||
|
|
||||||
|
# ===== TEMPLATE ENGINE =====
|
||||||
|
# Jinja2 und MarkupSafe (automatisch mit Flask installiert, aber explizit für utils/template_helpers.py)
|
||||||
|
{template_requirements}
|
||||||
|
|
||||||
|
# ===== SYSTEM MONITORING =====
|
||||||
|
# psutil für System-Monitoring (utils/debug_utils.py, utils/debug_cli.py)
|
||||||
|
{monitoring_requirements}
|
||||||
|
|
||||||
|
# ===== ZUSÄTZLICHE CORE ABHÄNGIGKEITEN =====
|
||||||
|
# Click für CLI-Kommandos (automatisch mit Flask)
|
||||||
|
{core_requirements}
|
||||||
|
|
||||||
|
# ===== WINDOWS-SPEZIFISCHE ABHÄNGIGKEITEN =====
|
||||||
|
# Nur für Windows-Systeme erforderlich
|
||||||
|
{windows_requirements}
|
||||||
|
|
||||||
|
# ===== OPTIONAL: ENTWICKLUNG UND TESTING =====
|
||||||
|
# Nur für Entwicklungsumgebung
|
||||||
|
{dev_requirements}
|
||||||
|
|
||||||
|
# ===== OPTIONAL: PRODUKTIONS-SERVER =====
|
||||||
|
# Gunicorn für Produktionsumgebung
|
||||||
|
{prod_requirements}
|
||||||
|
"""
|
||||||
|
|
||||||
|
# Requirements kategorisieren
|
||||||
|
flask_reqs = [r for r in requirements if any(x in r.lower() for x in ['flask'])]
|
||||||
|
db_reqs = [r for r in requirements if 'SQLAlchemy' in r]
|
||||||
|
security_reqs = [r for r in requirements if any(x in r for x in ['Werkzeug', 'bcrypt', 'cryptography'])]
|
||||||
|
smartplug_reqs = [r for r in requirements if 'PyP100' in r]
|
||||||
|
cache_reqs = [r for r in requirements if 'redis' in r]
|
||||||
|
http_reqs = [r for r in requirements if 'requests' in r]
|
||||||
|
template_reqs = [r for r in requirements if any(x in r for x in ['Jinja2', 'MarkupSafe', 'itsdangerous'])]
|
||||||
|
monitoring_reqs = [r for r in requirements if 'psutil' in r]
|
||||||
|
core_reqs = [r for r in requirements if any(x in r for x in ['click', 'blinker'])]
|
||||||
|
windows_reqs = [r for r in requirements if 'sys_platform' in r]
|
||||||
|
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
content = header.format(
|
||||||
|
date=datetime.now().strftime('%Y-%m-%d %H:%M:%S'),
|
||||||
|
flask_requirements='\n'.join(flask_reqs) or '# Keine Flask-spezifischen Requirements',
|
||||||
|
db_requirements='\n'.join(db_reqs) or '# Keine Datenbank-Requirements',
|
||||||
|
security_requirements='\n'.join(security_reqs) or '# Keine Sicherheits-Requirements',
|
||||||
|
smartplug_requirements='\n'.join(smartplug_reqs) or '# Keine Smart Plug Requirements',
|
||||||
|
cache_requirements='\n'.join(cache_reqs) or '# Keine Cache-Requirements',
|
||||||
|
http_requirements='\n'.join(http_reqs) or '# Keine HTTP-Requirements',
|
||||||
|
template_requirements='\n'.join(template_reqs) or '# Keine Template-Requirements',
|
||||||
|
monitoring_requirements='\n'.join(monitoring_reqs) or '# Keine Monitoring-Requirements',
|
||||||
|
core_requirements='\n'.join(core_reqs) or '# Keine Core-Requirements',
|
||||||
|
windows_requirements='\n'.join(windows_reqs) or '# Keine Windows-Requirements',
|
||||||
|
dev_requirements='pytest==8.3.4; extra == "dev"\npytest-cov==6.0.0; extra == "dev"',
|
||||||
|
prod_requirements='gunicorn==23.0.0; extra == "prod"'
|
||||||
|
)
|
||||||
|
|
||||||
|
with open(output_file, 'w', encoding='utf-8') as f:
|
||||||
|
f.write(content)
|
||||||
|
|
||||||
|
def main():
|
||||||
|
"""Hauptfunktion."""
|
||||||
|
print("🔄 MYP Platform Requirements Update")
|
||||||
|
print("=" * 50)
|
||||||
|
|
||||||
|
# Projekt-Root ermitteln
|
||||||
|
project_root = Path(__file__).parent
|
||||||
|
|
||||||
|
print(f"📁 Projekt-Verzeichnis: {project_root}")
|
||||||
|
|
||||||
|
# Imports sammeln
|
||||||
|
print("\n📋 Sammle Imports aus wichtigen Dateien...")
|
||||||
|
imports = get_all_imports(project_root)
|
||||||
|
|
||||||
|
print(f"\n📦 Gefundene externe Imports: {len(imports)}")
|
||||||
|
for imp in sorted(imports):
|
||||||
|
print(f" - {imp}")
|
||||||
|
|
||||||
|
# Aktuelle Versionen abrufen
|
||||||
|
print("\n🔍 Prüfe installierte Versionen...")
|
||||||
|
versions = get_current_versions()
|
||||||
|
|
||||||
|
# Requirements generieren
|
||||||
|
print("\n⚙️ Generiere Requirements...")
|
||||||
|
requirements = generate_requirements(imports, versions)
|
||||||
|
|
||||||
|
# Requirements-Datei schreiben
|
||||||
|
output_file = project_root / 'requirements.txt'
|
||||||
|
write_requirements_file(requirements, output_file)
|
||||||
|
|
||||||
|
print(f"\n✅ Requirements aktualisiert: {output_file}")
|
||||||
|
print(f"📊 {len(requirements)} Pakete in requirements.txt")
|
||||||
|
|
||||||
|
# Zusammenfassung
|
||||||
|
print("\n📋 Generierte Requirements:")
|
||||||
|
for req in requirements:
|
||||||
|
print(f" - {req}")
|
||||||
|
|
||||||
|
print("\n🎉 Requirements-Update abgeschlossen!")
|
||||||
|
print("\nNächste Schritte:")
|
||||||
|
print("1. pip install -r requirements.txt")
|
||||||
|
print("2. Anwendung testen")
|
||||||
|
print("3. requirements-dev.txt und requirements-prod.txt bei Bedarf anpassen")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
main()
|
Reference in New Issue
Block a user