Benutzer-Werkzeuge

Webseiten-Werkzeuge


projekt:python_fastapi1

Unterschiede

Hier werden die Unterschiede zwischen zwei Versionen angezeigt.

Link zu dieser Vergleichsansicht

Nächste Überarbeitung
Vorhergehende Überarbeitung
projekt:python_fastapi1 [2026/02/21 10:57] – angelegt torsten.roehlprojekt:python_fastapi1 [2026/02/21 13:22] (aktuell) – gelöscht torsten.roehl
Zeile 1: Zeile 1:
-====== Python FASTAPI ====== 
  
-[[raspberry_pi:einstiegskurs_raspberry_pi|☚ zurück - Einstiegskurs Raspberry Pi]] 
- 
- 
-//In diesem Projekt wird auf dem Raspberry Pi eine Weboberfläche mit FastAPI erstellt, über die eine LED-Ampel geschaltet und die Temperatur eines DS18B20 angezeigt werden kann. Die Anwendung ist im lokalen Netzwerk erreichbar, sodass LEDs und Temperatursensor bequem über einen Webbrowser im LAN gesteuert und überwacht werden können.// 
-====== Überblick ====== 
-  * Voraussetzungen 
-  * Software 
-  * Konfiguration 
- 
-====== Details ====== 
- 
-===== Voraussetzungen ===== 
- 
-==== ENV ==== 
- 
-<note important> 
-**Aktivierung der Python-Environment: ''course_env''** 
- 
-Alle weiteren Schritte erfolgen mit der aktivierten Python-Umgebung. 
- 
-<code> 
-source ~/devel/projects/course_env/bin/activate 
-</code> 
- 
-</note> 
-Anschließend werden FastAPI und Uvicorn installiert: 
- 
-<code bash> 
-pip install fastapi uvicorn        
-</code> 
-<note> 
-**FastAPI / Uvicorn** 
- 
-  * **FastAPI** 
-    * stellt das Web-Framework bereit, mit dem die Webseiten und Routen programmiert werden. 
-  * **Uvicorn** 
-    * startet die Anwendung und sorgt dafür, dass sie im Browser erreichbar ist. 
-</note> 
- 
-==== Projektstruktur ==== 
- 
-'' cd ~/devel/projects/'' 
-<code> 
-course_web/ 
-└── src/ 
-    ├── app.py 
-    ├── core/ 
-    │   |── __init__.py    # kann leer sein!     
-    │   └── hardware.py 
-    └── html/ 
-        ├── led.html 
-        └── temp.html 
- 
-</code> 
-==== Apache2 Startseite ==== 
-Im Verzeichnis des Apache2-Webservers (''/var/www/html'') wird eine ''index.html'' bereitgestellt.  
-Beim Aufruf der **IP-Adresse des Raspberry Pi im Browser** wird diese Startseite geladen, über die anschließend das gewünschte Projekt ausgewählt werden kann. 
- 
-<note tip> **Tip** 
- 
-Bevor die neue ''index.html'' im Verzeichnis ''/var/www/html'' erstellt wird, sollte die vorhandene Apache-Standardseite ''index.html'' gesichert werden. 
-<code bash> 
-sudo mv /var/www/html/index.html /var/www/html/index_course_backup.html 
-</code> 
-</note> 
- 
-<code html /var/www/html/index.html> 
-<!DOCTYPE html> 
-<html> 
-<head> 
-    <title>Projekt Auswahl</title> 
-</head> 
-<body> 
- 
-<h1>Projekt Auswahl</h1> 
- 
-<ul> 
-    <li><a href="/wiki">DokuWiki</a></li> 
-    <li><a href="/led">LED Ampel</a></li> 
-    <li><a href="/temp">Temperatur</a></li> 
-</ul> 
- 
-</body> 
-</html> 
-</code> 
-==== Hardware ==== 
-Die Hardware, also die LED-Ampel und der Temperatursensor, wurden in den vorausgegangenen Projekten ausführlich behandelt und werden exakt so verwendet wie dort beschrieben. 
- 
-===== Software ===== 
-Im folgenden Abschnitt werden die für die Webanwendung benötigten Python- und HTML-Dateien vorgestellt. Dazu gehören die Hardware-Anbindung über GPIO und den Temperatursensor, die HTML-Seiten zur Darstellung im Browser sowie die FastAPI-Anwendung, welche die Routen bereitstellt und die einzelnen Komponenten miteinander verbindet. 
-==== API ==== 
- 
-<code python /home/pi/devel/projects/course_web/src/core/hardware.py > 
-import RPi.GPIO as GPIO 
-import glob 
-import time 
- 
-# ----------------------------- 
-# API-Funktionen GPIO LED Ampel 
-# ----------------------------- 
- 
-PIN_R = 17 
-PIN_Y = 27 
-PIN_G = 22 
- 
-_initialized = False 
- 
-def init(): 
-    global _initialized 
-    if _initialized: 
-        return 
- 
-    GPIO.setwarnings(False) 
-    GPIO.setmode(GPIO.BCM) 
- 
-    GPIO.setup(PIN_R, GPIO.OUT) 
-    GPIO.setup(PIN_Y, GPIO.OUT) 
-    GPIO.setup(PIN_G, GPIO.OUT) 
- 
-    _initialized = True 
- 
- 
-def setLED(pin, value): 
-    GPIO.output(pin, GPIO.HIGH if value == 1 else GPIO.LOW) 
- 
- 
-def setRedLED(value): 
-    setLED(PIN_R, value) 
- 
- 
-def setYellowLED(value): 
-    setLED(PIN_Y, value) 
- 
- 
-def setGreenLED(value): 
-    setLED(PIN_G, value) 
- 
- 
-def status(): 
-    return ( 
-        int(GPIO.input(PIN_R)), 
-        int(GPIO.input(PIN_Y)), 
-        int(GPIO.input(PIN_G)), 
-    ) 
- 
- 
-# ----------------------------- 
-# API-Funktionen ds18b20 
-# ----------------------------- 
- 
-SENSOR_TIMEOUT = 1 
- 
-def get_sensor(): 
-    sensors = glob.glob("/sys/bus/w1/devices/28-*") 
-    if not sensors: 
-        return None 
-    return sensors[0] + "/w1_slave" 
- 
- 
-def get_temperature(): 
-    sensor_file = get_sensor() 
-    if sensor_file is None: 
-        return None 
- 
-    start_time = time.time() 
- 
-    while True: 
-        with open(sensor_file, "r") as f: 
-            lines = f.readlines() 
- 
-        if lines[0].strip().endswith("YES"): 
-            break 
- 
-        if time.time() - start_time > SENSOR_TIMEOUT: 
-            return None 
- 
-        time.sleep(0.1) 
- 
-    temp_line = lines[1] 
-    temp_str = temp_line.split("t=")[1] 
-    return float(temp_str) / 1000.0 
-</code> 
- 
- 
-====  HTML ==== 
- 
-=== LED === 
- 
- 
-<code html /home/pi/devel/projects/course_web/src/html/led.html> 
-<!DOCTYPE html> 
-<html> 
-<head> 
-    <title>LED Ampel</title> 
-</head> 
-<body> 
- 
-<h1>LED Ampel</h1> 
- 
-<h2>Rot</h2> 
-<p>Status: {{R}}</p> 
-<a href="/led/r/1">ON</a> 
-<a href="/led/r/0">OFF</a> 
- 
-<h2>Gelb</h2> 
-<p>Status: {{Y}}</p> 
-<a href="/led/y/1">ON</a> 
-<a href="/led/y/0">OFF</a> 
- 
-<h2>Grün</h2> 
-<p>Status: {{G}}</p> 
-<a href="/led/g/1">ON</a> 
-<a href="/led/g/0">OFF</a> 
- 
-<br><br> 
-<a href="/">Zurück</a> 
- 
-</body> 
-</html> 
-</code> 
- 
- 
-=== Temperature === 
- 
- 
-<code html /home/pi/devel/projects/course_web/src/html/temp.html> 
-<!DOCTYPE html> 
-<html> 
-<head> 
-    <title>Temperatur</title> 
-</head> 
-<body> 
- 
-<h1>Temperatur</h1> 
- 
-<p>Temperatur: {{T}} °C</p> 
- 
-<br> 
-<a href="/">Zurück</a> 
- 
-</body> 
-</html> 
-</code> 
- 
- 
-==== FASTAPI APP ==== 
- 
- 
-<code python /home/pi/devel/projects/course_web/src/app.py> 
- 
- 
-from fastapi import FastAPI, HTTPException 
-from fastapi.responses import HTMLResponse, RedirectResponse 
-from core import hardware 
- 
-app = FastAPI() 
- 
- 
-@app.on_event("startup") 
-def startup(): 
-    hardware.init() 
- 
- 
-def load_template(name, replacements): 
-    try: 
-        with open(f"html/{name}", "r") as f: 
-            html = f.read() 
-    except FileNotFoundError: 
-        raise HTTPException(status_code=500, detail="Template nicht gefunden") 
- 
-    for key, value in replacements.items(): 
-        html = html.replace(key, str(value)) 
- 
-    return html 
- 
- 
-@app.get("/led", response_class=HTMLResponse) 
-def led_page(): 
-    r, y, g = hardware.status() 
-    return HTMLResponse( 
-        load_template("led.html", { 
-            "{{R}}": r, 
-            "{{Y}}": y, 
-            "{{G}}": g 
-        }) 
-    ) 
- 
- 
-@app.get("/led/{color}/{value}") 
-def set_led(color: str, value: int): 
- 
-    if value not in (0, 1): 
-        raise HTTPException(status_code=400) 
- 
-    if color == "r": 
-        hardware.setRedLED(value) 
-    elif color == "y": 
-        hardware.setYellowLED(value) 
-    elif color == "g": 
-        hardware.setGreenLED(value) 
-    else: 
-        raise HTTPException(status_code=400) 
- 
-    return RedirectResponse(url="/led", status_code=303) 
- 
- 
-@app.get("/temp", response_class=HTMLResponse) 
-def temp_page(): 
-    t = hardware.get_temperature() 
- 
-    if t is None: 
-        value = "Sensorfehler" 
-    else: 
-        value = f"{t:.2f}" 
- 
-    return HTMLResponse( 
-        load_template("temp.html", { 
-            "{{T}}": value 
-        }) 
-    ) 
-</code> 
- 
- 
- 
- 
-===== Konfiguration ===== 
-In diesem Abschnitt wird die Einbindung der **FastAPI-Anwendung** in den Apache-Webserver sowie die Einrichtung als ''systemd-Service'' beschrieben, damit die Anwendung automatisch startet und im lokalen Netzwerk erreichbar ist. 
-==== Apache Proxy ==== 
- 
-=== Konfiguration === 
- 
-In der Datei '' /etc/apache2/sites-available/000-default.conf'', innerhalb von ''<VirtualHost *:80>'' folgendes einfügen: 
- 
-<code bash /etc/apache2/sites-available/000-default.conf> 
-ProxyPreserveHost On 
- 
-ProxyPass        /led   http://127.0.0.1:8000/led 
-ProxyPassReverse /led   http://127.0.0.1:8000/led 
- 
-ProxyPass        /temp  http://127.0.0.1:8000/temp 
-ProxyPassReverse /temp  http://127.0.0.1:8000/temp 
-</code> 
- 
-=== Aktivieren === 
-<code bash> 
-sudo a2enmod proxy 
-sudo a2enmod proxy_http 
-sudo systemctl restart apache2 
-</code> 
- 
-==== Systemd ==== 
- 
-Die Service-Datei muss unter ''/etc/systemd/system/course_web.service'' neu erstellt und anschließend bei ''systemd'' registriert werden. 
-=== Service === 
- 
- 
-<code bash /etc/systemd/system/course_web.service> 
-[Unit] 
-Description=Python Web FastAPI 
-After=network-online.target 
-Wants=network-online.target 
- 
-[Service] 
-User=pi 
-WorkingDirectory=/home/pi/devel/projects/course_web/src 
-ExecStart=/home/pi/devel/projects/course_env/bin/uvicorn app:app --host 127.0.0.1 --port 8000 
-Restart=always 
- 
-[Install] 
-WantedBy=multi-user.target 
-</code> 
- 
-=== Registrierung === 
-<code bash> 
-sudo systemctl daemon-reload 
-sudo systemctl enable course_web 
-sudo systemctl start course_web       # starten 
-sudo systemctl status course_web      # prüfen!!! 
-</code> 
projekt/python_fastapi1.1771671474.txt.gz · Zuletzt geändert: von torsten.roehl