added restful api
This commit is contained in:
commit
4e359cf3ef
7 changed files with 530 additions and 0 deletions
38
backend/.gitignore
vendored
Normal file
38
backend/.gitignore
vendored
Normal file
|
@ -0,0 +1,38 @@
|
||||||
|
# Virtual Environment
|
||||||
|
venv/
|
||||||
|
|
||||||
|
# Python
|
||||||
|
__pycache__/
|
||||||
|
*.py[cod]
|
||||||
|
*$py.class
|
||||||
|
*.so
|
||||||
|
.Python
|
||||||
|
build/
|
||||||
|
develop-eggs/
|
||||||
|
dist/
|
||||||
|
downloads/
|
||||||
|
eggs/
|
||||||
|
.eggs/
|
||||||
|
lib/
|
||||||
|
lib64/
|
||||||
|
parts/
|
||||||
|
sdist/
|
||||||
|
var/
|
||||||
|
wheels/
|
||||||
|
*.egg-info/
|
||||||
|
.installed.cfg
|
||||||
|
*.egg
|
||||||
|
|
||||||
|
# IDE
|
||||||
|
.vscode/
|
||||||
|
.idea/
|
||||||
|
*.swp
|
||||||
|
*.swo
|
||||||
|
*~
|
||||||
|
|
||||||
|
# OS
|
||||||
|
.DS_Store
|
||||||
|
Thumbs.db
|
||||||
|
|
||||||
|
# Logs
|
||||||
|
*.log
|
220
backend/README.md
Normal file
220
backend/README.md
Normal file
|
@ -0,0 +1,220 @@
|
||||||
|
# Tschunk Order API
|
||||||
|
|
||||||
|
Eine RESTful API für Tschunk-Bestellungen, entwickelt mit FastAPI.
|
||||||
|
|
||||||
|
## Features
|
||||||
|
|
||||||
|
- Bestellungen mit mehreren Getränken erstellen
|
||||||
|
- Alle Bestellungen abrufen
|
||||||
|
- Spezifische Bestellungen löschen
|
||||||
|
- Unterstützung für verschiedene Tschunk-Varianten
|
||||||
|
- Wahl zwischen Flora Mate und Club Mate
|
||||||
|
- Mengenangabe für jedes Getränk (Standard: 1)
|
||||||
|
- Anmerkungen und Sonderwünsche für jedes Getränk
|
||||||
|
|
||||||
|
## Verfügbare Getränke
|
||||||
|
|
||||||
|
- **Tschunk**
|
||||||
|
- **Tschunk Hannover-Mische**
|
||||||
|
- **Tschunk alkoholfreier Rum**
|
||||||
|
- **Virgin Tschunk**
|
||||||
|
|
||||||
|
## Mate-Sorten
|
||||||
|
|
||||||
|
- **Flora Mate**
|
||||||
|
- **Club Mate**
|
||||||
|
|
||||||
|
## Installation
|
||||||
|
|
||||||
|
### Voraussetzungen
|
||||||
|
|
||||||
|
- Python 3.8+ installiert
|
||||||
|
|
||||||
|
### Setup
|
||||||
|
|
||||||
|
1. **Virtuelles Environment erstellen und aktivieren:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
cd backend
|
||||||
|
|
||||||
|
# Virtuelles Environment erstellen
|
||||||
|
python -m venv venv
|
||||||
|
|
||||||
|
# Virtuelles Environment aktivieren
|
||||||
|
# Unter Linux/macOS:
|
||||||
|
source venv/bin/activate
|
||||||
|
|
||||||
|
# Unter Windows:
|
||||||
|
# venv\Scripts\activate
|
||||||
|
```
|
||||||
|
|
||||||
|
2. **Abhängigkeiten installieren:**
|
||||||
|
|
||||||
|
```bash
|
||||||
|
pip install -r requirements.txt
|
||||||
|
```
|
||||||
|
|
||||||
|
## Verwendung
|
||||||
|
|
||||||
|
### Server starten
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Stelle sicher, dass das virtuelle Environment aktiviert ist
|
||||||
|
source venv/bin/activate # Linux/macOS
|
||||||
|
# venv\Scripts\activate # Windows
|
||||||
|
|
||||||
|
# Server starten
|
||||||
|
python main.py
|
||||||
|
```
|
||||||
|
|
||||||
|
Oder mit uvicorn:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uvicorn main:app --reload
|
||||||
|
```
|
||||||
|
|
||||||
|
Der Server läuft dann auf `http://localhost:8000`
|
||||||
|
|
||||||
|
### API-Dokumentation
|
||||||
|
|
||||||
|
Die automatisch generierte API-Dokumentation ist verfügbar unter:
|
||||||
|
- Swagger UI: `http://localhost:8000/docs`
|
||||||
|
- ReDoc: `http://localhost:8000/redoc`
|
||||||
|
|
||||||
|
## API-Endpunkte
|
||||||
|
|
||||||
|
### 1. Bestellung erstellen
|
||||||
|
```
|
||||||
|
POST /orders
|
||||||
|
```
|
||||||
|
|
||||||
|
Beispiel-Request:
|
||||||
|
```json
|
||||||
|
{
|
||||||
|
"drinks": [
|
||||||
|
{
|
||||||
|
"drink_type": "Tschunk",
|
||||||
|
"mate_type": "Club Mate",
|
||||||
|
"quantity": 2,
|
||||||
|
"notes": "Bitte extra kalt servieren"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"drink_type": "Virgin Tschunk",
|
||||||
|
"mate_type": "Flora Mate",
|
||||||
|
"notes": "Ohne Eiswürfel"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"drink_type": "Tschunk Hannover-Mische",
|
||||||
|
"mate_type": "Club Mate",
|
||||||
|
"quantity": 1
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
```
|
||||||
|
|
||||||
|
**Hinweise:**
|
||||||
|
- Das `quantity`-Feld ist optional. Falls nicht angegeben, wird automatisch 1 verwendet.
|
||||||
|
- Das `notes`-Feld ist optional und kann für Sonderwünsche oder Anmerkungen verwendet werden (max. 500 Zeichen).
|
||||||
|
|
||||||
|
### 2. Alle Bestellungen abrufen
|
||||||
|
```
|
||||||
|
GET /orders
|
||||||
|
```
|
||||||
|
|
||||||
|
### 3. Bestellung löschen
|
||||||
|
```
|
||||||
|
DELETE /orders/{order_id}
|
||||||
|
```
|
||||||
|
|
||||||
|
### 4. Verfügbare Getränke anzeigen
|
||||||
|
```
|
||||||
|
GET /drinks
|
||||||
|
```
|
||||||
|
|
||||||
|
## Beispiel-Verwendung mit curl
|
||||||
|
|
||||||
|
### Bestellung erstellen:
|
||||||
|
```bash
|
||||||
|
curl -X POST "http://localhost:8000/orders" \
|
||||||
|
-H "Content-Type: application/json" \
|
||||||
|
-d '{
|
||||||
|
"drinks": [
|
||||||
|
{
|
||||||
|
"drink_type": "Tschunk",
|
||||||
|
"mate_type": "Club Mate",
|
||||||
|
"quantity": 3,
|
||||||
|
"notes": "Bitte mit Limettenscheibe garnieren"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"drink_type": "Virgin Tschunk",
|
||||||
|
"mate_type": "Flora Mate",
|
||||||
|
"notes": "Allergie gegen Zitrusfrüchte"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}'
|
||||||
|
```
|
||||||
|
|
||||||
|
### Alle Bestellungen abrufen:
|
||||||
|
```bash
|
||||||
|
curl -X GET "http://localhost:8000/orders"
|
||||||
|
```
|
||||||
|
|
||||||
|
### Bestellung löschen:
|
||||||
|
```bash
|
||||||
|
curl -X DELETE "http://localhost:8000/orders/{order_id}"
|
||||||
|
```
|
||||||
|
|
||||||
|
## Testing
|
||||||
|
|
||||||
|
Das Projekt enthält ein Test-Skript, das alle API-Endpunkte testet:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Stelle sicher, dass das virtuelle Environment aktiviert ist
|
||||||
|
source venv/bin/activate
|
||||||
|
|
||||||
|
# Test-Skript ausführen
|
||||||
|
python test_api.py
|
||||||
|
```
|
||||||
|
|
||||||
|
## Projektstruktur
|
||||||
|
|
||||||
|
```
|
||||||
|
backend/
|
||||||
|
├── main.py # FastAPI-Anwendung
|
||||||
|
├── models.py # Pydantic-Modelle
|
||||||
|
├── database.py # In-Memory-Datenbank
|
||||||
|
├── test_api.py # Test-Skript
|
||||||
|
├── requirements.txt # Python-Abhängigkeiten
|
||||||
|
├── .gitignore # Git-Ignore-Datei
|
||||||
|
├── venv/ # Virtuelles Environment (wird ignoriert)
|
||||||
|
└── README.md # Diese Datei
|
||||||
|
```
|
||||||
|
|
||||||
|
## Hinweise
|
||||||
|
|
||||||
|
- **Virtuelles Environment**: Das Projekt verwendet ein virtuelles Environment, um Abhängigkeiten zu isolieren
|
||||||
|
- **In-Memory-Datenbank**: Die API verwendet eine In-Memory-Datenbank, d.h. alle Daten gehen beim Neustart verloren
|
||||||
|
- **Produktionsumgebung**: Für Produktionsumgebungen sollte eine persistente Datenbank verwendet werden
|
||||||
|
- **Validierung**: Die API validiert automatisch alle Eingaben mit Pydantic
|
||||||
|
- **Mengenangabe**: Jedes Getränk kann eine Menge haben (mindestens 1, Standard: 1)
|
||||||
|
- **Anmerkungen**: Jedes Getränk kann optionale Anmerkungen haben (max. 500 Zeichen)
|
||||||
|
|
||||||
|
## Troubleshooting
|
||||||
|
|
||||||
|
### Virtuelles Environment aktivieren
|
||||||
|
Falls du eine Fehlermeldung bezüglich fehlender Module erhältst, stelle sicher, dass das virtuelle Environment aktiviert ist:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
# Status prüfen
|
||||||
|
which python # Sollte auf venv/bin/python zeigen
|
||||||
|
|
||||||
|
# Falls nicht aktiviert:
|
||||||
|
source venv/bin/activate
|
||||||
|
```
|
||||||
|
|
||||||
|
### Port bereits belegt
|
||||||
|
Falls Port 8000 bereits belegt ist, kannst du einen anderen Port verwenden:
|
||||||
|
|
||||||
|
```bash
|
||||||
|
uvicorn main:app --reload --port 8001
|
||||||
|
```
|
39
backend/database.py
Normal file
39
backend/database.py
Normal file
|
@ -0,0 +1,39 @@
|
||||||
|
from typing import List, Optional
|
||||||
|
import uuid
|
||||||
|
from datetime import datetime
|
||||||
|
from models import Order, Drink
|
||||||
|
|
||||||
|
|
||||||
|
class OrderDatabase:
|
||||||
|
def __init__(self):
|
||||||
|
self.orders: dict[str, Order] = {}
|
||||||
|
|
||||||
|
def create_order(self, drinks: List[Drink]) -> Order:
|
||||||
|
"""Create a new order with the given drinks."""
|
||||||
|
order_id = str(uuid.uuid4())
|
||||||
|
order = Order(
|
||||||
|
id=order_id,
|
||||||
|
order_date=datetime.now(),
|
||||||
|
drinks=drinks
|
||||||
|
)
|
||||||
|
self.orders[order_id] = order
|
||||||
|
return order
|
||||||
|
|
||||||
|
def get_all_orders(self) -> List[Order]:
|
||||||
|
"""Get all orders."""
|
||||||
|
return list(self.orders.values())
|
||||||
|
|
||||||
|
def get_order_by_id(self, order_id: str) -> Optional[Order]:
|
||||||
|
"""Get a specific order by ID."""
|
||||||
|
return self.orders.get(order_id)
|
||||||
|
|
||||||
|
def delete_order(self, order_id: str) -> bool:
|
||||||
|
"""Delete an order by ID. Returns True if successful, False if not found."""
|
||||||
|
if order_id in self.orders:
|
||||||
|
del self.orders[order_id]
|
||||||
|
return True
|
||||||
|
return False
|
||||||
|
|
||||||
|
|
||||||
|
# Global database instance
|
||||||
|
db = OrderDatabase()
|
62
backend/main.py
Normal file
62
backend/main.py
Normal file
|
@ -0,0 +1,62 @@
|
||||||
|
from fastapi import FastAPI, HTTPException
|
||||||
|
from typing import List
|
||||||
|
from models import CreateOrderRequest, Order, DrinkType, MateType
|
||||||
|
from database import db
|
||||||
|
|
||||||
|
app = FastAPI(
|
||||||
|
title="Tschunk Order API",
|
||||||
|
description="Eine RESTful API für Tschunk-Bestellungen",
|
||||||
|
version="1.0.0"
|
||||||
|
)
|
||||||
|
|
||||||
|
@app.post("/orders", response_model=Order, status_code=201)
|
||||||
|
async def create_order(order_request: CreateOrderRequest):
|
||||||
|
"""
|
||||||
|
Erstellt eine neue Bestellung.
|
||||||
|
|
||||||
|
- **drinks**: Liste der Getränke mit Typ und Mate-Sorte
|
||||||
|
"""
|
||||||
|
if not order_request.drinks:
|
||||||
|
raise HTTPException(status_code=400, detail="Mindestens ein Getränk muss bestellt werden")
|
||||||
|
|
||||||
|
order = db.create_order(order_request.drinks)
|
||||||
|
return order
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/orders", response_model=List[Order])
|
||||||
|
async def get_all_orders():
|
||||||
|
"""
|
||||||
|
Gibt alle Bestellungen zurück.
|
||||||
|
"""
|
||||||
|
orders = db.get_all_orders()
|
||||||
|
return orders
|
||||||
|
|
||||||
|
|
||||||
|
@app.delete("/orders/{order_id}")
|
||||||
|
async def delete_order(order_id: str):
|
||||||
|
"""
|
||||||
|
Löscht eine spezifische Bestellung.
|
||||||
|
|
||||||
|
- **order_id**: ID der zu löschenden Bestellung
|
||||||
|
"""
|
||||||
|
success = db.delete_order(order_id)
|
||||||
|
if not success:
|
||||||
|
raise HTTPException(status_code=404, detail="Bestellung nicht gefunden")
|
||||||
|
|
||||||
|
return {"message": f"Bestellung {order_id} wurde erfolgreich gelöscht"}
|
||||||
|
|
||||||
|
|
||||||
|
@app.get("/drinks")
|
||||||
|
async def get_available_drinks():
|
||||||
|
"""
|
||||||
|
Gibt alle verfügbaren Getränketypen zurück.
|
||||||
|
"""
|
||||||
|
return {
|
||||||
|
"drink_types": [drink.value for drink in DrinkType],
|
||||||
|
"mate_types": [mate.value for mate in MateType]
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
import uvicorn
|
||||||
|
uvicorn.run(app, host="0.0.0.0", port=8000)
|
33
backend/models.py
Normal file
33
backend/models.py
Normal file
|
@ -0,0 +1,33 @@
|
||||||
|
from pydantic import BaseModel, Field
|
||||||
|
from typing import List, Optional
|
||||||
|
from datetime import datetime
|
||||||
|
from enum import Enum
|
||||||
|
|
||||||
|
|
||||||
|
class MateType(str, Enum):
|
||||||
|
FLORA_MATE = "Flora Mate"
|
||||||
|
CLUB_MATE = "Club Mate"
|
||||||
|
|
||||||
|
|
||||||
|
class DrinkType(str, Enum):
|
||||||
|
TSCHUNK = "Tschunk"
|
||||||
|
TSCHUNK_HANNOVER_MISCHE = "Tschunk Hannover-Mische"
|
||||||
|
TSCHUNK_ALKOHOLFREIER_RUM = "Tschunk alkoholfreier Rum"
|
||||||
|
VIRGIN_TSCHUNK = "Virgin Tschunk"
|
||||||
|
|
||||||
|
|
||||||
|
class Drink(BaseModel):
|
||||||
|
drink_type: DrinkType
|
||||||
|
mate_type: MateType
|
||||||
|
quantity: int = Field(default=1, ge=1, description="Anzahl der bestellten Getränke")
|
||||||
|
notes: Optional[str] = Field(default=None, max_length=500, description="Sonderwünsche oder Anmerkungen zum Getränk")
|
||||||
|
|
||||||
|
|
||||||
|
class Order(BaseModel):
|
||||||
|
id: str
|
||||||
|
order_date: datetime
|
||||||
|
drinks: List[Drink]
|
||||||
|
|
||||||
|
|
||||||
|
class CreateOrderRequest(BaseModel):
|
||||||
|
drinks: List[Drink]
|
5
backend/requirements.txt
Normal file
5
backend/requirements.txt
Normal file
|
@ -0,0 +1,5 @@
|
||||||
|
fastapi>=0.115.0
|
||||||
|
uvicorn[standard]>=0.32.0
|
||||||
|
pydantic>=2.10.0
|
||||||
|
python-multipart>=0.0.20
|
||||||
|
requests>=2.32.0
|
133
backend/test_api.py
Normal file
133
backend/test_api.py
Normal file
|
@ -0,0 +1,133 @@
|
||||||
|
#!/usr/bin/env python3
|
||||||
|
"""
|
||||||
|
Test-Skript für die Tschunk Order API
|
||||||
|
"""
|
||||||
|
|
||||||
|
import requests
|
||||||
|
import json
|
||||||
|
from datetime import datetime
|
||||||
|
|
||||||
|
BASE_URL = "http://localhost:8000"
|
||||||
|
|
||||||
|
def test_api():
|
||||||
|
"""Testet alle API-Endpunkte."""
|
||||||
|
|
||||||
|
print("🚀 Starte API-Tests...\n")
|
||||||
|
|
||||||
|
# Test 1: Root endpoint
|
||||||
|
print("1. Teste Root-Endpoint...")
|
||||||
|
try:
|
||||||
|
response = requests.get(f"{BASE_URL}/")
|
||||||
|
print(f"✅ Root endpoint: {response.status_code}")
|
||||||
|
print(f" Verfügbare Getränke: {response.json()['available_drinks']}")
|
||||||
|
print(f" Verfügbare Mate-Sorten: {response.json()['available_mate_types']}\n")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Fehler beim Root endpoint: {e}\n")
|
||||||
|
|
||||||
|
# Test 2: Getränke anzeigen
|
||||||
|
print("2. Teste Getränke-Endpoint...")
|
||||||
|
try:
|
||||||
|
response = requests.get(f"{BASE_URL}/drinks")
|
||||||
|
print(f"✅ Getränke endpoint: {response.status_code}")
|
||||||
|
print(f" Getränke: {response.json()}\n")
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Fehler beim Getränke endpoint: {e}\n")
|
||||||
|
|
||||||
|
# Test 3: Bestellung erstellen (mit quantity und notes)
|
||||||
|
print("3. Teste Bestellung erstellen (mit Mengenangabe und Sonderwünschen)...")
|
||||||
|
test_order = {
|
||||||
|
"drinks": [
|
||||||
|
{
|
||||||
|
"drink_type": "Tschunk",
|
||||||
|
"mate_type": "Club Mate",
|
||||||
|
"quantity": 2,
|
||||||
|
"notes": "Bitte extra kalt servieren"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"drink_type": "Virgin Tschunk",
|
||||||
|
"mate_type": "Flora Mate"
|
||||||
|
# quantity und notes werden nicht angegeben, sollten automatisch 1 bzw. None sein
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"drink_type": "Tschunk Hannover-Mische",
|
||||||
|
"mate_type": "Club Mate",
|
||||||
|
"quantity": 3,
|
||||||
|
"notes": "Ohne Eiswürfel, bitte mit Limettenscheibe"
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|
||||||
|
try:
|
||||||
|
response = requests.post(
|
||||||
|
f"{BASE_URL}/orders",
|
||||||
|
json=test_order,
|
||||||
|
headers={"Content-Type": "application/json"}
|
||||||
|
)
|
||||||
|
print(f"✅ Bestellung erstellt: {response.status_code}")
|
||||||
|
order_data = response.json()
|
||||||
|
print(f" Bestell-ID: {order_data['id']}")
|
||||||
|
print(f" Bestelldatum: {order_data['order_date']}")
|
||||||
|
print(f" Anzahl Getränke: {len(order_data['drinks'])}")
|
||||||
|
|
||||||
|
# Zeige Details der Getränke
|
||||||
|
for i, drink in enumerate(order_data['drinks']):
|
||||||
|
notes_info = f" (Anmerkung: {drink['notes']})" if drink.get('notes') else ""
|
||||||
|
print(f" - Getränk {i+1}: {drink['drink_type']} mit {drink['mate_type']} (Menge: {drink['quantity']}){notes_info}")
|
||||||
|
|
||||||
|
# Speichere Order-ID für späteren Test
|
||||||
|
order_id = order_data['id']
|
||||||
|
print()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Fehler beim Erstellen der Bestellung: {e}")
|
||||||
|
return
|
||||||
|
|
||||||
|
# Test 4: Alle Bestellungen abrufen
|
||||||
|
print("4. Teste Alle Bestellungen abrufen...")
|
||||||
|
try:
|
||||||
|
response = requests.get(f"{BASE_URL}/orders")
|
||||||
|
print(f"✅ Alle Bestellungen: {response.status_code}")
|
||||||
|
orders = response.json()
|
||||||
|
print(f" Anzahl Bestellungen: {len(orders)}")
|
||||||
|
for order in orders:
|
||||||
|
total_quantity = sum(drink['quantity'] for drink in order['drinks'])
|
||||||
|
drinks_with_notes = sum(1 for drink in order['drinks'] if drink.get('notes'))
|
||||||
|
print(f" - Bestellung {order['id']}: {len(order['drinks'])} verschiedene Getränke (Gesamtmenge: {total_quantity}, {drinks_with_notes} mit Anmerkungen)")
|
||||||
|
print()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Fehler beim Abrufen der Bestellungen: {e}\n")
|
||||||
|
|
||||||
|
# Test 5: Bestellung löschen
|
||||||
|
print("5. Teste Bestellung löschen...")
|
||||||
|
try:
|
||||||
|
response = requests.delete(f"{BASE_URL}/orders/{order_id}")
|
||||||
|
print(f"✅ Bestellung gelöscht: {response.status_code}")
|
||||||
|
print(f" Nachricht: {response.json()['message']}")
|
||||||
|
print()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Fehler beim Löschen der Bestellung: {e}\n")
|
||||||
|
|
||||||
|
# Test 6: Bestätige Löschung
|
||||||
|
print("6. Bestätige Löschung...")
|
||||||
|
try:
|
||||||
|
response = requests.get(f"{BASE_URL}/orders")
|
||||||
|
orders = response.json()
|
||||||
|
print(f"✅ Verbleibende Bestellungen: {len(orders)}")
|
||||||
|
print()
|
||||||
|
except Exception as e:
|
||||||
|
print(f"❌ Fehler beim Abrufen der Bestellungen: {e}\n")
|
||||||
|
|
||||||
|
print("🎉 API-Tests abgeschlossen!")
|
||||||
|
|
||||||
|
if __name__ == "__main__":
|
||||||
|
print("=" * 50)
|
||||||
|
print("Tschunk Order API - Test Suite")
|
||||||
|
print("=" * 50)
|
||||||
|
print()
|
||||||
|
print("⚠️ Stelle sicher, dass der Server auf http://localhost:8000 läuft!")
|
||||||
|
print()
|
||||||
|
|
||||||
|
# Frage nach Bestätigung
|
||||||
|
input("Drücke Enter um fortzufahren...")
|
||||||
|
print()
|
||||||
|
|
||||||
|
test_api()
|
Loading…
Add table
Add a link
Reference in a new issue