192 lines
5.6 KiB
Markdown
192 lines
5.6 KiB
Markdown
# Python-Nutzung in diesem Projekt
|
|
|
|
Diese Anleitung ist fuer KI-Coder und Entwickler gedacht, die in diesem Projekt Python-Skripte aus PHP heraus verwenden oder erweitern wollen.
|
|
|
|
## Ziel
|
|
|
|
Python soll hier nicht als dauerhaft laufender Dienst verwendet werden, sondern als einzelnes Skript, das von einer PHP-Seite per `exec(...)` gestartet wird.
|
|
|
|
Bevorzugtes Muster in diesem Projekt:
|
|
|
|
- eine zentrale Python-Datei als Einstiegspunkt: `public/py/api.py`
|
|
- darin mehrere Aktionen, z. B. `sun_moon_rise_set`
|
|
- PHP uebergibt zuerst den Aktionsnamen und danach die Argumente
|
|
|
|
Typischer Ablauf:
|
|
|
|
1. Eine PHP-Seite sammelt Eingabedaten.
|
|
2. PHP ruft `public/py/api.py` auf.
|
|
3. Das Python-Skript berechnet das Ergebnis.
|
|
4. Python gibt das Ergebnis als JSON auf `stdout` aus.
|
|
5. PHP liest dieses JSON ein und rendert die Seite.
|
|
|
|
## Wichtige Projektregeln
|
|
|
|
- Der zentrale Einstiegspunkt fuer Webaufrufe liegt in `public/py/api.py`.
|
|
- Wenn moeglich, soll Python JSON ausgeben, nicht frei formatierten Text.
|
|
- Fehler sollen ebenfalls als JSON ausgegeben werden, damit PHP sie sauber anzeigen kann.
|
|
- Die PHP-Seite ist fuer Eingabevalidierung, Aufruf und Darstellung zustaendig.
|
|
- Das Python-Skript ist fuer die Berechnung zustaendig.
|
|
- Neue Funktionen sollen bevorzugt als neue Aktion in `api.py` ergaenzt werden, nicht als neue Einzeldatei.
|
|
|
|
## Lokale Astronomy Engine
|
|
|
|
In diesem Projekt liegt die Python-Version der Astronomy Engine bereits lokal als:
|
|
|
|
- `public/py/astronomy.py`
|
|
|
|
Deshalb koennen Python-Skripte aus demselben Ordner sie direkt importieren, zum Beispiel:
|
|
|
|
```python
|
|
import os
|
|
import sys
|
|
|
|
SCRIPT_DIR = os.path.dirname(os.path.abspath(__file__))
|
|
if SCRIPT_DIR not in sys.path:
|
|
sys.path.insert(0, SCRIPT_DIR)
|
|
|
|
import astronomy
|
|
```
|
|
|
|
Das ist wichtig, damit der Import auch auf Hosting-Systemen funktioniert, auf denen kein global installiertes Paket vorhanden ist.
|
|
|
|
## PHP-Aufruf
|
|
|
|
Die Python-Skripte werden in diesem Projekt per `exec(...)` aus PHP gestartet.
|
|
|
|
Beispielmuster:
|
|
|
|
```php
|
|
$command = '/usr/bin/python ' . escapeshellarg($scriptPath) . ' ' . implode(' ', $args) . ' 2>&1';
|
|
$output = [];
|
|
$resultCode = 0;
|
|
exec($command, $output, $resultCode);
|
|
```
|
|
|
|
Mit zentraler API-Datei sieht der Aufruf typischerweise so aus:
|
|
|
|
```php
|
|
$args = [
|
|
escapeshellarg($scriptPath),
|
|
escapeshellarg('sun_moon_rise_set'),
|
|
escapeshellarg($latitude),
|
|
escapeshellarg($longitude),
|
|
escapeshellarg($elevation),
|
|
escapeshellarg($date),
|
|
escapeshellarg($timezone),
|
|
];
|
|
```
|
|
|
|
Wichtig:
|
|
|
|
- Immer `escapeshellarg(...)` fuer alle dynamischen Argumente verwenden.
|
|
- `2>&1` anhängen, damit Fehlermeldungen mitgelesen werden.
|
|
- Rueckgabecode pruefen.
|
|
- Ausgabe mit `json_decode(...)` verarbeiten.
|
|
|
|
## Hosting-Hinweis fuer All-Inkl
|
|
|
|
Nach der All-Inkl-Anleitung werden Shell-Skripte bzw. Python-Skripte ueber PHP typischerweise so gestartet:
|
|
|
|
```php
|
|
exec("/usr/bin/python Pfad/zum/script 2>&1", $out, $result);
|
|
```
|
|
|
|
Quelle:
|
|
|
|
- https://all-inkl.com/wichtig/anleitungen/skripte/sonstiges/per-skript/shellskripte-ausfuehren_304.html
|
|
|
|
Wichtige Punkte aus der Anleitung:
|
|
|
|
- Python kann per `/usr/bin/python` aufgerufen werden.
|
|
- Nicht alle Shell-Befehle sind auf dem Hosting erlaubt.
|
|
- Groessere Skripte koennen an Serverrestriktionen scheitern.
|
|
- Falls zusaetzliche Python-Module gebraucht werden, koennen sie per SSH in ein eigenes Zielverzeichnis installiert werden.
|
|
- Falls ein eigenes Modulverzeichnis genutzt wird, muss dieses im Python-Skript per `sys.path.append(...)` eingebunden werden.
|
|
|
|
Beispiel aus der All-Inkl-Logik:
|
|
|
|
```python
|
|
import sys
|
|
sys.path.append("/www/htdocs/ACCOUNTNAME/python-module")
|
|
```
|
|
|
|
## Empfohlenes JSON-Format
|
|
|
|
Python sollte moeglichst ein einheitliches Antwortformat liefern.
|
|
|
|
Erfolg:
|
|
|
|
```json
|
|
{
|
|
"ok": true,
|
|
"data": {
|
|
"example": 123
|
|
}
|
|
}
|
|
```
|
|
|
|
Fehler:
|
|
|
|
```json
|
|
{
|
|
"ok": false,
|
|
"error": "Beschreibung des Fehlers"
|
|
}
|
|
```
|
|
|
|
So kann PHP sehr einfach unterscheiden:
|
|
|
|
```php
|
|
$decoded = json_decode($joinedOutput, true);
|
|
if (!is_array($decoded) || !($decoded['ok'] ?? false)) {
|
|
// Fehler behandeln
|
|
}
|
|
```
|
|
|
|
## Beispiel in diesem Projekt
|
|
|
|
Bereits umgesetzt ist:
|
|
|
|
- `public/index_py.php`
|
|
- `public/py/api.py`
|
|
|
|
Dort wird gezeigt:
|
|
|
|
- wie Standortdaten aus PHP uebergeben werden,
|
|
- wie Python mit `astronomy.py` rechnet,
|
|
- wie JSON zurueckgegeben wird,
|
|
- und wie Fehler im PHP angezeigt werden.
|
|
|
|
## Best Practices fuer KI-Coder
|
|
|
|
- Vor neuen Python-Dateien zuerst pruefen, ob die neue Funktion als weitere Aktion in `api.py` eingebaut werden kann.
|
|
- CLI-Argumente immer strikt validieren.
|
|
- Niemals unescaped Benutzereingaben in Shell-Kommandos einsetzen.
|
|
- Python-Ausgabe kompakt halten, idealerweise genau eine JSON-Zeile.
|
|
- Bei Fehlern maschinenlesbar bleiben.
|
|
- Zeitangaben moeglichst mit Zeitzone oder als ISO-Format ausgeben.
|
|
- Rechenlogik in Python halten, HTML-Ausgabe in PHP.
|
|
- Bei Hosting-Fragen zuerst mit `/usr/bin/python` planen, weil das fuer All-Inkl dokumentiert ist.
|
|
|
|
## Checkliste vor dem Einbau
|
|
|
|
- Wird moeglichst `public/py/api.py` verwendet?
|
|
- Sind alle CLI-Argumente in PHP mit `escapeshellarg(...)` abgesichert?
|
|
- Gibt Python gueltiges JSON aus?
|
|
- Werden Fehlerfaelle ebenfalls als JSON behandelt?
|
|
- Ist der Import lokaler Module ueber `sys.path` abgesichert?
|
|
- Ist klar, welche Zeitzone verwendet wird?
|
|
- Ist das Skript klein genug fuer Shared-Hosting?
|
|
|
|
## Kurzfassung
|
|
|
|
In diesem Projekt gilt:
|
|
|
|
- PHP startet Python per `exec(...)`.
|
|
- Zentraler Einstiegspunkt ist `public/py/api.py`.
|
|
- Die gewuenschte Funktion wird ueber einen Aktionsnamen ausgewaehlt.
|
|
- Ergebnisse kommen als JSON zurueck.
|
|
- Lokale Bibliotheken wie `astronomy.py` werden direkt aus dem `py`-Ordner importiert.
|
|
- Auf All-Inkl ist `/usr/bin/python` der Standardweg fuer den Aufruf.
|