commit cda71fb8c1807c50519166a340c67c4d307a5978 Author: Adam Skotarczak Date: Thu Apr 24 13:52:37 2025 +0200 initial commit diff --git a/.env.example b/.env.example new file mode 100644 index 0000000..692b5fe --- /dev/null +++ b/.env.example @@ -0,0 +1,10 @@ +# APP_MODE ungenutzt im Template (production/ development) +APP_MODE=development + +# LOGLEVEL: "CRITICAL"- "ERROR" - "WARNING" - "INFO" - "DEBUG" +LOGLEVEL=INFO + +# Pfad zum log z.B log/template.log (relativ und absolut beachten!) +# Pfad ist ausgehend vom Ort der run.py und Verzeichnisse werden automatisch erstellt. +# DEFAULT: log/template.log +LOGFILE=log/template.log diff --git a/.gitignore b/.gitignore new file mode 100644 index 0000000..bd3237b --- /dev/null +++ b/.gitignore @@ -0,0 +1,184 @@ +# Byte-compiled / optimized / DLL files +__pycache__/ +*.py[cod] +*$py.class + +# C extensions +*.so + +# Distribution / packaging +.Python +build/ +develop-eggs/ +dist/ +downloads/ +eggs/ +.eggs/ +lib/ +lib64/ +parts/ +sdist/ +var/ +wheels/ +share/python-wheels/ +*.egg-info/ +.installed.cfg +*.egg +MANIFEST + +# PyInstaller +# Usually these files are written by a python script from a template +# before PyInstaller builds the exe, so as to inject date/other infos into it. +*.manifest +*.spec + +# Installer logs +pip-log.txt +pip-delete-this-directory.txt + +# Unit test / coverage reports +htmlcov/ +.tox/ +.nox/ +.coverage +.coverage.* +.cache +nosetests.xml +coverage.xml +*.cover +*.py,cover +.hypothesis/ +.pytest_cache/ +cover/ + +# Translations +*.mo +*.pot + +# Django stuff: +*.log +local_settings.py +db.sqlite3 +db.sqlite3-journal + +# Flask stuff: +instance/ +.webassets-cache + +# Scrapy stuff: +.scrapy + +# Sphinx documentation +docs/_build/ + +# PyBuilder +.pybuilder/ +target/ + +# Jupyter Notebook +.ipynb_checkpoints + +# IPython +profile_default/ +ipython_config.py + +# pyenv +# For a library or package, you might want to ignore these files since the code is +# intended to run in multiple environments; otherwise, check them in: +# .python-version + +# pipenv +# According to pypa/pipenv#598, it is recommended to include Pipfile.lock in version control. +# However, in case of collaboration, if having platform-specific dependencies or dependencies +# having no cross-platform support, pipenv may install dependencies that don't work, or not +# install all needed dependencies. +#Pipfile.lock + +# UV +# Similar to Pipfile.lock, it is generally recommended to include uv.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +#uv.lock + +# poetry +# Similar to Pipfile.lock, it is generally recommended to include poetry.lock in version control. +# This is especially recommended for binary packages to ensure reproducibility, and is more +# commonly ignored for libraries. +# https://python-poetry.org/docs/basic-usage/#commit-your-poetrylock-file-to-version-control +#poetry.lock + +# pdm +# Similar to Pipfile.lock, it is generally recommended to include pdm.lock in version control. +#pdm.lock +# pdm stores project-wide configurations in .pdm.toml, but it is recommended to not include it +# in version control. +# https://pdm.fming.dev/latest/usage/project/#working-with-version-control +.pdm.toml +.pdm-python +.pdm-build/ + +# PEP 582; used by e.g. github.com/David-OConnor/pyflow and github.com/pdm-project/pdm +__pypackages__/ + +# Celery stuff +celerybeat-schedule +celerybeat.pid + +# SageMath parsed files +*.sage.py + +# Environments +.env +.env.* +!.env.example +.venv +env/ +venv/ +ENV/ +env.bak/ +venv.bak/ + +# Spyder project settings +.spyderproject +.spyproject + +# Rope project settings +.ropeproject + +# mkdocs documentation +/site + +# mypy +.mypy_cache/ +.dmypy.json +dmypy.json + +# Pyre type checker +.pyre/ + +# pytype static type analyzer +.pytype/ + +# Cython debug symbols +cython_debug/ + +# PyCharm +# JetBrains specific template is maintained in a separate JetBrains.gitignore that can +# be found at https://github.com/github/gitignore/blob/main/Global/JetBrains.gitignore +# and can be added to the global gitignore or merged into this file. For a more nuclear +# option (not recommended) you can uncomment the following to ignore the entire idea folder. +#.idea/ + +# Ruff stuff: +.ruff_cache/ + +# PyPI configuration file +.pypirc + +# Custom: +logs/ +log/ +release/ +#media/ +*.zip +NOTES.md diff --git a/.vscode/extensions.json b/.vscode/extensions.json new file mode 100644 index 0000000..efcd059 --- /dev/null +++ b/.vscode/extensions.json @@ -0,0 +1,7 @@ +{ + "recommendations": [ + "ms-python.python", + "ms-python.vscode-pylance", + "ms-toolsai.jupyter" + ] + } diff --git a/.vscode/settings.jsonc b/.vscode/settings.jsonc new file mode 100644 index 0000000..8c46f9c --- /dev/null +++ b/.vscode/settings.jsonc @@ -0,0 +1,30 @@ +{ // Bitte daran denken das Kommentare eigentlich nicht von json unterstützt werden :-) + // Das funktioniert hier nur in Microsofts jsonc im VS-Code! + "python.linting.enabled": true, + "python.linting.pylintEnabled": true, + "python.linting.mypyEnabled": true, + "python.linting.pylintArgs": ["--disable=C0114,C0115,C0116"], + "editor.formatOnSave": true, + "editor.codeActionsOnSave": { + "source.organizeImports": "explicit" + }, + "python.analysis.typeCheckingMode": "basic", + + // Abschliessende Leerzeichen entfernen: + "files.trimTrailingWhitespace": true, + "files.insertFinalNewline": true, + + // Markdown für das Entfernen von abschliessenden Leerzeichen rausnehmen: + "[markdown]": { + "files.trimTrailingWhitespace": false, + "editor.wordWrap": "off" + }, + + // Für Pythonfiles Tababstand definieren und Tabs durch Leerzeichen ersetzen + "[python]": { + "editor.tabSize": 4, + "editor.insertSpaces": true + }, + + + } diff --git a/.vscode/tasks.json b/.vscode/tasks.json new file mode 100644 index 0000000..388da81 --- /dev/null +++ b/.vscode/tasks.json @@ -0,0 +1,17 @@ +{ + "version": "2.0.0", + "tasks": [ + { + "label": "Linter (pylint)", + "type": "shell", + "command": "pylint beispiel.py", + "group": "build" + }, + { + "label": "Typprüfung (mypy)", + "type": "shell", + "command": "mypy beispiel.py", + "group": "build" + } + ] + } diff --git a/CHANGELOG.md b/CHANGELOG.md new file mode 100644 index 0000000..f019dd6 --- /dev/null +++ b/CHANGELOG.md @@ -0,0 +1,14 @@ +# CHANGELOG - Python Flask Template + +- [CHANGELOG - Python Flask Template](#changelog---python-flask-template) + - [2025-..-.. - Commit v1.0.1](#2025-----commit-v101) + - [2025-..-.. - Release v1.0.0](#2025-----release-v100) + +## 2025-..-.. - Commit v1.0.1 + +- **Geändert:** + - [ ] + +## 2025-..-.. - Release v1.0.0 + +- **Release 1.0.0** 🚀 diff --git a/README.md b/README.md new file mode 100644 index 0000000..1749054 --- /dev/null +++ b/README.md @@ -0,0 +1,254 @@ +# Python Bootstrap-Flask-Template mit `.venv`- und `.env` Support + +![Logo](./media/logo.png) + +> ⚙️ Dieses Projekt verwendet [Git Subtree](SUBTREE.md) zur Integration des Basis-Templates. Details siehe [`SUBTREE.md`](SUBTREE.md). + +Dieses Template nutzt PEP 8, Type Hints, Docstrings und einen vordefinierten Workspace für sauberen Python-Code. +Außerdem bietet es ein portables Start-Template für Python-Anwendungen mit folgenden Features: + +- Automatische Erstellung einer virtuellen Umgebung (`.venv`) +- Automatische Installation von Abhängigkeiten aus `requirements.txt` +- Automatischer Neustart in der virtuellen Umgebung +- Unterstützung von Umgebungsvariablen über eine `.env`-Datei +- Sauberer Einstiegspunkt über `run.py` +- Keine systemweiten Python-Pakete notwendig +- Logging-Utils bereits integriert + +Das Template ist durchdacht, pragmatisch und stark auf Entwicklerkomfort ausgelegt. +Es bietet eine sehr gute Grundlage für Projekte aller Art – insbesondere CLI-Tools, kleine Services und lokale Anwendungen. Die automatische Einrichtung der virtuellen Umgebung hebt es funktional deutlich von Standard-Vorlagen ab. + +**Was dieses template __nicht__ ist:** + +- [ ] [pep-518](https://peps.python.org/pep-0518/)-konform 🚫 + +> ⚠️ Dieses Template verfolgt kein komplexes Build-System. +Es ist dafür gedacht, dir in Sekunden eine saubere, gekapselte Python-Umgebung bereitzustellen – perfekt zum schnellen Testen, Debuggen oder Projektstart. +Einfach deinen Code in main.py werfen, bei Bedarf requirements.txt anpassen, run.py starten – fertig. Kein Setup-Wahnsinn, kein Overhead. + +--- + +## 🔜 Inhalt der Readme + +- [Python Bootstrap-Flask-Template mit `.venv`- und `.env` Support](#python-bootstrap-flask-template-mit-venv--und-env-support) + - [🔜 Inhalt der Readme](#-inhalt-der-readme) + - [🔧 Projektstruktur](#-projektstruktur) + - [🚀 Erste Schritte](#-erste-schritte) + - [Beim ersten Start passiert:](#beim-ersten-start-passiert) + - [📦 Abhängigkeiten](#-abhängigkeiten) + - [⚙️ .env-Datei (optional)](#️-env-datei-optional) + - [📜 Beispielausgabe](#-beispielausgabe) + - [🪵 Logging](#-logging) + - [🔧 Konfiguration (in `.env`)](#-konfiguration-in-env) + - [📥 Beispielausgabe](#-beispielausgabe-1) + - [📌 Logik im Code](#-logik-im-code) + - [📁 Logrotation](#-logrotation) + - [🛠 Hinweise](#-hinweise) + - [🧪 Getestet mit](#-getestet-mit) + - [🛠 Einsatz von `Linter` (`pylint`)](#-einsatz-von-linter-pylint) + - [📁 Lizenz](#-lizenz) + +--- + +## 🔧 Projektstruktur + +```plaintext + +📁 template-root/ +├── 📁 .vscode/ # Projekteinstellungen VS-Code +│ ├── 📄 settings.json # Einstellungen +│ └── 📄 extensions.json # Erweiterungen +├── 📄 .env # Projektkonfiguration (optional, nicht im git) +├── 📄 .env.example # Vorlage der .env +├── 📄 requirements.txt # Abhängigkeiten (z.B. python-dotenv) +├── 📄 README.md # diese Datei +├── 📄 CHANGELOG.md # +├── 📄 VERSION # Versionsinfo zum Paket +├── 📄 run.py # Einstiegspunkt für die Anwendung +├── 📁 media/ +│ └── 📄 logo.png # Logo für GitHub +└── 📁 app/ + ├── 📄 __init__.py # + ├── 📄 main.py # Hauptlogik der Anwendung + └── 📄 bootstrap.py # Setup- und Relaunch-Logik +``` + +> Release-Pakete als `.zip` sind bereits von unötigem Balast bereinigt. Die dargestellte Struktur entspricht einem `git clone`. + +[🔝](#-inhalt-der-readme) + +--- + +## 🚀 Erste Schritte + +- [ ] `.env.example` in `.env` umbenennen und individuell befüllen. +- [ ] `.vscode`-Verzeichnis löschen, wenn du eigene Einstellungen nutzt. Ich habe es versehentlich committet und aus Bequemlichkeit drin gelassen, weil es meinem Standard entspicht. +- [ ] `requirements.txt` auf deine Bedürfnisse anpassen. +- [ ] `media/`Verzeichnis Löschen falls vorhanden. + +**Erster Start des Templates:** + +```bash +python run.py +``` + +### Beim ersten Start passiert: + +1. `.venv` wird erstellt (wenn noch nicht vorhanden) +2. `requirements.txt` wird installiert +3. Das Skript wird automatisch innerhalb der venv neu gestartet +4. `.env` wird geladen (falls vorhanden) +5. **Die App startet 🚀** + +> Es erfolgen einige Ausgaben, die alle aus der `main.py` stammen, außer du `DEBUG` in der `.env` aktiviert hast. + +[🔝](#-inhalt-der-readme) + +--- + +## 📦 Abhängigkeiten + +Alle Abhängigkeiten werden aus `requirements.txt` installiert. +**Beispiel:** + +```text +python-dotenv +``` + +[🔝](#-inhalt-der-readme) + +--- + +## ⚙️ .env-Datei (optional) + +Wenn vorhanden, wird `.env` automatisch geladen. +**Beispiel:** + +```dotenv +APP_MODE=development +LOGLEVEL=debug +PORT=8080 +``` + +Diese Werte sind im Code über `os.getenv("APP_MODE")` verfügbar. + +[🔝](#-inhalt-der-readme) + +--- + +## 📜 Beispielausgabe + +```text +[BOOTSTRAP] Erstelle virtuelle Umgebung... +[BOOTSTRAP] Installiere pip + requirements.txt... +[BOOTSTRAP] Starte in virtueller Umgebung neu... +[RUN] Lade .env aus: ./cliqrcode/.env +[APP] Starte Anwendung im Modus: development +[APP] Hello, world! +``` + +[🔝](#-inhalt-der-readme) + +--- + +## 🪵 Logging + +Dieses Template verwendet ein integriertes Logging-Modul mit folgenden Eigenschaften: + +- Ausgabe in die Konsole (immer aktiv) +- Optionale Ausgabe in eine Logdatei (`LOGFILE`) +- Unterstützung für rotierende Logdateien +- Loglevel konfigurierbar über `.env` +- Plattformunabhängig (Windows, Linux, macOS) +- Keine externen Abhängigkeiten + +### 🔧 Konfiguration (in `.env`) + +```dotenv +LOGLEVEL=INFO # Möglich: DEBUG, INFO, WARNING, ERROR, CRITICAL +LOGFILE=logs/app.log # Optionaler Pfad zur Logdatei (relativ oder absolut) +``` + +> Wenn `LOGFILE` nicht gesetzt ist, wird nur in die Konsole geloggt. + +### 📥 Beispielausgabe + +```bash +[2025-04-23 14:10:00] INFO app.main: Template ready. +[2025-04-23 14:10:00] DEBUG app.main: Dies ist eine Debug-Meldung. +``` + +### 📌 Logik im Code + +In beliebigen Modulen kannst du so einen Logger verwenden: + +```python +from app.logging_utils import get_logger + +log = get_logger(__name__) +log.info("Template ready.") +``` + +### 📁 Logrotation + +Die Logdatei wird bei 1 MB automatisch rotiert (max. 3 Backups), z. B.: + +```bash +logs/app.log +logs/app.log.1 +logs/app.log.2 +``` + +[🔝](#-inhalt-der-readme) + +--- + +## 🛠 Hinweise + +- Das Template ist portabel und benötigt keine global installierten Pakete. +- Du kannst es für jede neue App wiederverwenden. +- `run.py` ist der einzige Einstiegspunkt – keine direkten Aufrufe von `main.py`. + +[🔝](#-inhalt-der-readme) + +--- + +## 🧪 Getestet mit + +- Python 3.11, 3.12, 3.13 +- Windows & Linux +- VS Code, Terminal, PowerShell + +[🔝](#-inhalt-der-readme) + +--- + +## 🛠 Einsatz von `Linter` (`pylint`) + +```cmd +PS C:\Users\adams\Documents\template> .\.venv\Scripts\activate +``` + +```cmd +(.venv) PS C:\Users\adams\Documents\template> pylint.exe run.py +``` + +```cmd +************* Module run +run.py:27:4: C0412: Imports from package app are not grouped (ungrouped-imports) +run.py:12:0: W0611: Unused import os (unused-import) + +----------------------------------- +Your code has been rated at 8.33/10 +``` + +**Bonus:** +Durch den Einsatz der <.vscode/task.json> für VS-Code, kannst du in VS-Code mit `Strg + Umschalt + P` → `Tasks: Run Task` → `Linter (pylint)` oder `Typprüfung (mypy)` aufrufen. + +[🔝](#-inhalt-der-readme) + +--- + +## 📁 Lizenz + +MIT – frei verwendbar in eigenen Projekten. diff --git a/SUBTREE.md b/SUBTREE.md new file mode 100644 index 0000000..ffa400b --- /dev/null +++ b/SUBTREE.md @@ -0,0 +1,20 @@ +# 🌳 Subtree-Konfiguration + +Dieses Projekt verwendet einen Git-Subtree zum Einbinden des Basis-Templates: + +## 📦 Eingebundenes Repository + +- **Name:** `python-template` +- **Quelle:** +- **Branch:** `main` +- **Pfad im Projekt:** `base/` + +## 🛠 Einrichtung (einmalig) + +```bash +git remote add python-template https://github.com/realAscot/python-template.git +git fetch python-template +git subtree add --prefix base python-template main --squash +``` + +Dies betrifft dich hautsächlich NUR, wenn Du aktiv an diesem Template weiterentickeln möchtest. diff --git a/VERSION b/VERSION new file mode 100644 index 0000000..7dea76e --- /dev/null +++ b/VERSION @@ -0,0 +1 @@ +1.0.1 diff --git a/app/__init__.py b/app/__init__.py new file mode 100644 index 0000000..c82a910 --- /dev/null +++ b/app/__init__.py @@ -0,0 +1,8 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Hier liegen die Dateien für die primäre Logik der Anwendung + +Diese Information hier stammt aus der datei ./app/__init__.py +""" diff --git a/app/bootstrap.py b/app/bootstrap.py new file mode 100644 index 0000000..3118381 --- /dev/null +++ b/app/bootstrap.py @@ -0,0 +1,71 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Bootstrap-Modul für automatische Einrichtung und Start der App. +Dieses Modul stellt sicher, dass: +- eine .venv angelegt ist +- python -m pip install -r requirements.txt ausgeführt wurde +- das Skript in der .venv neu gestartet wird, falls nötig +""" + +import os +import subprocess +import sys +from pathlib import Path + +# Pfad zur virtuellen Umgebung im Projektverzeichnis +VENV_DIR = Path(__file__).resolve().parent.parent / ".venv" +# Pfad zum Python-Interpreter in der venv +PYTHON_EXE = VENV_DIR / ("Scripts" if os.name == "nt" else "bin") / "python" + + +def ensure_venv(): + """ + Prüft, ob die .venv existiert und ob das aktuelle Skript + bereits innerhalb der venv ausgeführt wird. + Falls nicht, wird: + - die .venv erstellt + - requirements.txt installiert + - das Skript in der .venv neu gestartet + """ + if os.environ.get("BOOTSTRAPPED") == "1": + return # Bereits innerhalb der .venv → nichts tun + + if not VENV_DIR.exists(): + _create_venv() + + if Path(sys.executable).resolve() != PYTHON_EXE.resolve(): + _relaunch() + + +def _create_venv(): + """ + Legt eine virtuelle Umgebung im Projektverzeichnis an + und installiert alle Pakete aus requirements.txt. + """ + print("[BOOTSTRAP] Erstelle virtuelle Umgebung...") + subprocess.check_call([sys.executable, "-m", "venv", str(VENV_DIR)]) + + print("[BOOTSTRAP] Installiere pip + requirements.txt...") + subprocess.check_call([str(PYTHON_EXE), "-m", "pip", "install", "--upgrade", "pip"]) + + req_file = Path(__file__).resolve().parent.parent / "requirements.txt" + if req_file.exists(): + subprocess.check_call( + [str(PYTHON_EXE), "-m", "pip", "install", "-r", str(req_file)] + ) + else: + print( + "[BOOTSTRAP] ⚠️ Keine requirements.txt gefunden – Installation übersprungen." + ) + + +def _relaunch(): + """ + Startet das Skript innerhalb der .venv neu. + Verwendet os.execv(), um den Prozess vollständig zu ersetzen. + """ + print("\n[BOOTSTRAP] Starte in virtueller Umgebung neu...") + os.environ["BOOTSTRAPPED"] = "1" + os.execv(str(PYTHON_EXE), [str(PYTHON_EXE)] + sys.argv) diff --git a/app/logging_utils.py b/app/logging_utils.py new file mode 100644 index 0000000..958a744 --- /dev/null +++ b/app/logging_utils.py @@ -0,0 +1,70 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Zentrales Logging-Modul +→ Unterstützt LOGLEVEL und LOGFILE aus der .env +→ Plattformunabhängig (Windows/Linux) +→ Erstellt automatisch das Log-Verzeichnis bei Bedarf +→ Fällt bei ungültigem Log-Level sicher auf INFO zurück +""" + +import logging +import os +from logging.handlers import RotatingFileHandler +from pathlib import Path + + +def safe_log_level(level_str: str) -> int: + """Wandelt einen Level-String in einen gültigen Logging-Level um.""" + levels = { + "CRITICAL": logging.CRITICAL, + "ERROR": logging.ERROR, + "WARNING": logging.WARNING, + "INFO": logging.INFO, + "DEBUG": logging.DEBUG, + "NOTSET": logging.NOTSET, + } + return levels.get(level_str.upper(), logging.INFO) + + +LOGLEVEL = safe_log_level(os.getenv("LOGLEVEL", "INFO")) +LOGFILE = os.getenv("LOGFILE", "log/app.log") # z. B. logs/app.log + + +def get_logger(name: str) -> logging.Logger: + logger = logging.getLogger(name) + if logger.handlers: + return logger # Logger bereits konfiguriert + + logger.setLevel(LOGLEVEL) + + formatter = logging.Formatter("[%(asctime)s] %(levelname)s %(name)s: %(message)s") + + # Konsole + console_handler = logging.StreamHandler() + console_handler.setFormatter(formatter) + logger.addHandler(console_handler) + + # Datei (optional) + if LOGFILE: + logfile_path = Path(LOGFILE) + + # Debug: Logpfad anzeigen (nur bei DEBUG) + if logger.isEnabledFor(logging.DEBUG): + try: + logger.debug(f"Logdatei: {logfile_path.resolve()}") + except Exception: + pass # Debug-Ausgabe darf nicht blockieren + + try: + logfile_path.parent.mkdir(parents=True, exist_ok=True) + file_handler = RotatingFileHandler( + logfile_path, maxBytes=1_000_000, backupCount=3, encoding="utf-8" + ) + file_handler.setFormatter(formatter) + logger.addHandler(file_handler) + except Exception as e: + logger.warning(f"Konnte Logdatei nicht schreiben: {e}") + + return logger diff --git a/app/main.py b/app/main.py new file mode 100644 index 0000000..d2849b4 --- /dev/null +++ b/app/main.py @@ -0,0 +1,41 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +./app/main.py + +Hier beginnt deine eigentliche Anwendung. +Alle Konfigurationen aus .env sind jetzt über os.getenv() verfügbar. +""" + +import os + +from app.logging_utils import get_logger + +log = get_logger(__name__) + + +def main(): + """ + Hier liegen die Dateien für die primäre Logik der Anwendung + Diese Information hier stammt aus der datei ./app/__init__.py + """ + # Hole APP_MODE aus der .env + mode = os.getenv("APP_MODE", "DEVEL") + + # Testausgabe: + print(f"[APP] 🚀 Starte Anwendung im Modus: {mode}") + print("[APP] 📦 -= Hello, world! =-") + + +def logtest(): + """ + wirft testweise alle Logvarianten aus. + """ + + print(f"\n[IFO] 📰 Loglevel aus .env: {os.getenv('LOGFILE')}\n") + log.info("Template ready.") + log.debug("Dies ist eine Debug-Meldung.") + log.warning("Dies ist eine Warnung.") + log.error("Dies ist eine Fehlermeldung.") + log.critical("Dies ist eine kritische Meldung.") diff --git a/media/logo.png b/media/logo.png new file mode 100644 index 0000000..9cadeef Binary files /dev/null and b/media/logo.png differ diff --git a/requirements.txt b/requirements.txt new file mode 100644 index 0000000..7c8383b --- /dev/null +++ b/requirements.txt @@ -0,0 +1,20 @@ +# -*- coding: utf-8 -*- + +# falls man .env verwenden möchte: +python-dotenv + +# Flask +flask + +# Projektbezogen ab hier: + + +# --- ALLES AB HIER IST OPTIONAL --- + +# Pytest, Linter und Typ-Prüfung (entfernen bei fertigem Code): +pytest +pytest-cov +pytest-mock +pylint +mypy + diff --git a/run.py b/run.py new file mode 100644 index 0000000..36c49e7 --- /dev/null +++ b/run.py @@ -0,0 +1,37 @@ +#!/usr/bin/env python3 +# -*- coding: utf-8 -*- + +""" +Einstiegspunkt der Anwendung. + +Sorgt dafür, dass beim ersten Start automatisch: +- eine virtuelle Umgebung (.venv) angelegt wird +- alle Abhängigkeiten installiert werden +- das Skript in der .venv neu gestartet wird +Erst danach wird die .env geladen und die App gestartet. +""" + +from app.bootstrap import ensure_venv + +if __name__ == "__main__": + ensure_venv() + + # .env laden – jetzt ist python-dotenv installiert (innerhalb der venv) + from dotenv import find_dotenv, load_dotenv + + dotenv_path = find_dotenv() + if dotenv_path: + print(f"\n[RUN] 🚀 Lade .env aus: {dotenv_path}") + load_dotenv(dotenv_path=dotenv_path, override=True) + else: + print("\n[RUN] ⚠️ Keine .env-Datei gefunden") + + # Ab hier deine Funktionen aufrufen: + + from app.main import main + + main() + + from app.main import logtest + + logtest()