"feat: Add update_requirements.py for managing Python dependencies"

This commit is contained in:
2025-05-29 19:42:23 +02:00
parent fa31208220
commit a4f6a472f3
3 changed files with 425 additions and 174 deletions

View File

@@ -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

View File

@@ -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

View 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()