Veröffentlicht: 27. Mai 2026 | Kategorie: KI-Integration Tutorial | Lesezeit: 12 Minuten
Stellen Sie sich vor: Es regnet 80mm pro Stunde, und Ihr Frühwarnsystem reagiert in Echtzeit – aggregiert Wetterdaten von GPT-5, extrahiert relevante Frames aus Überwachungsvideos via Gemini und verarbeitet alles mit stabiler SLA-Limitierung. Jetzt bei HolySheep anmelden und dieses System selbst aufbauen.
Inhaltsverzeichnis
- Was ist der HolySheep 城市内涝预警 Agent?
- Voraussetzungen für Einsteiger
- Schritt-für-Schritt: API-Zugang einrichten
- GPT-5 Rain Aggregation implementieren
- Gemini Video Frame Extraction
- SLA Rate Limiting & Retry konfigurieren
- Praxiserfahrung aus meinem Projekt
- Vergleich mit Alternativen
- Preise und ROI
- Häufige Fehler und Lösungen
- Kaufempfehlung
Was ist der HolySheep 城市内涝预警 Agent?
Der 城市内涝预警 Agent (Stadtüberschwemmungs-Frühwarnsystem-Agent) ist eine KI-gestützte Lösung für Kommunen, Versorgungsunternehmen und Smart-City-Dienstleister. Er kombiniert drei Kerntechnologien:
- GPT-5 Rain Aggregation: Fasst Regendaten aus mehreren Quellen (Radar, Sensoren, Wetter-APIs) zusammen und erkennt kritische Muster
- Gemini Video Frame Extraction: Analysiert Überwachungsvideos in Echtzeit und extrahiert relevante Frames bei Wasserstand-Überschreitungen
- SLA Rate Limiting: Stabile API-Nutzung mit automatischer Wiederholung bei Überlastung
💡 Tipp für Einsteiger: Sie brauchen keine Programmiererfahrung! Dieser Leitfaden erklärt alles von Grund auf mit copy-paste-fähigem Code.
Voraussetzungen für Einsteiger
Bevor wir beginnen, stellen Sie sicher, dass Sie folgende Grundlagen haben:
- HolySheep AI Account: Kostenlose Registrierung hier
- Python 3.9+: Installieren Sie von python.org
- Grundlegendes Verständnis: Wir erklären alle Fachbegriffe
Schritt-für-Schritt: API-Zugang einrichten
1. API-Key generieren
Nach der Registrierung finden Sie Ihren API-Key im Dashboard unter „API Keys" → „Neuen Key erstellen". Kopieren Sie den Schlüssel – er sieht so aus:
hs_live_a1b2c3d4e5f6g7h8i9j0...
(Screenshot-Hinweis: Dashboard → API Keys → Create New Key)
2. Python-Umgebung vorbereiten
# Installieren Sie die benötigten Pakete
pip install requests holySheep-sdk python-dotenv
Erstellen Sie eine .env Datei für Ihren API-Key
Datei: .env
Inhalt:
HOLYSHEEP_API_KEY=hs_live_a1b2c3d4e5f6g7h8i9j0
HOLYSHEEP_BASE_URL=https://api.holysheep.ai/v1
3. Basis-Client initialisieren
import os
import requests
from dotenv import load_dotenv
.env Datei laden
load_dotenv()
API-Konfiguration
API_KEY = os.getenv("HOLYSHEEP_API_KEY")
BASE_URL = "https://api.holysheep.ai/v1"
Testen der Verbindung
headers = {
"Authorization": f"Bearer {API_KEY}",
"Content-Type": "application/json"
}
response = requests.get(
f"{BASE_URL}/models",
headers=headers
)
if response.status_code == 200:
print("✅ Verbindung erfolgreich!")
print(f"Verfügbare Modelle: {len(response.json()['data'])}")
else:
print(f"❌ Fehler: {response.status_code}")
print(response.json())
GPT-5 Rain Aggregation implementieren
Was ist Rain Aggregation?
Bei Starkregen erhalten Sie Daten aus Dutzenden von Quellen: Radar, Regenmesser, Wetterstationen, Social Media. GPT-5 analysiert all diese Daten, erkennt Muster und erstellt eine einheitliche, handlungsrelevante Warnung.
Beispiel: Regen-Daten aggregieren
import requests
import json
from datetime import datetime
class RainAggregator:
def __init__(self, api_key):
self.api_key = api_key
self.base_url = "https://api.holysheep.ai/v1"
def aggregate_rain_data(self, sensor_data: list, weather_api_data: dict) -> dict:
"""
Aggregiert Regendaten aus mehreren Quellen mit GPT-5
Args:
sensor_data: Liste von Sensor-Messwerten
weather_api_data: Wetter-API Rohdaten
"""
# Prompt für die Aggregation
aggregation_prompt = f"""Analysiere die folgenden Regendaten für eine Stadtüberschwemmungs-Frühwarnung:
REGENDATEN (Sensoren):
{json.dumps(sensor_data, indent=2)}
WETTERDATEN:
{json.dumps(weather_api_data, indent=2)}
Erstelle eine strukturierte Analyse mit:
1. Gesamtniederschlag (mm/Stunde)
2. Gefährdungsstufe (1-5)
3. Betroffene Stadtteile
4. Empfohlene Maßnahmen
5. Prognose für nächste 2 Stunden
"""
payload = {
"model": "gpt-5", # GPT-5 für präzise Analyse
"messages": [
{
"role": "system",
"content": "Du bist ein Experte für Stadtüberschwemmungs-Analyse."
},
{
"role": "user",
"content": aggregation_prompt
}
],
"temperature": 0.3, # Niedrige Temperatur für konsistente Ergebnisse
"max_tokens": 1000
}
response = requests.post(
f"{self.base_url}/chat/completions",
headers={
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
},
json=payload
)
if response.status_code == 200:
result = response.json()
return {
"status": "success",
"analysis": result['choices'][0]['message']['content'],
"usage": result.get('usage', {}),
"timestamp": datetime.now().isoformat()
}
else:
raise Exception(f"API Fehler: {response.status_code} - {response.text}")
Beispiel-Nutzung
if __name__ == "__main__":
aggregator = RainAggregator(api_key="YOUR_HOLYSHEEP_API_KEY")
# Simulierte Sensordaten
sensor_data = [
{"station": "Nord-1", "rain_mm_h": 45, "water_level_m": 1.2},
{"station": "Süd-3", "rain_mm_h": 78, "water_level_m": 1.8},
{"station": "Ost-2", "rain_mm_h": 32, "water_level_m": 0.9},
]
weather_data = {
"source": "DWD",
"warning_level": "Orange",
"radar_intensity": "Heavy",
"next_2h_trend": "Increasing"
}
result = aggregator.aggregate_rain_data(sensor_data, weather_data)
print(json.dumps(result, indent=2, ensure_ascii=False))
Interpretation der Ergebnisse
GPT-5 gibt Ihnen strukturierte Warnungen zurück, die direkt in Ihre Dashboards oder Benachrichtigungssysteme integriert werden können. Die Latenz beträgt typischerweise unter 50ms bei HolySheep.
Gemini Video Frame Extraction
Video-Analyse für Überflutungsfrüherkennung
Überwachungskameras an kritischen Punkten (Unterführungen, Tunnel, Drainage-Ausgänge) liefern wertvolle visuellen Daten. Gemini 2.5 Flash extrahiert automatisch relevante Frames bei Wasserstand-Überschreitungen.
import base64
import requests
import json
class VideoFrameExtractor:
def __init__(self, api_key):
self.api_key = api_key
self.base_url = "https://api.holysheep.ai/v1"
def extract_flood_frames(self, video_path: str, threshold_m: float = 0.5) -> dict:
"""
Extrahiert Frames mit Wasserstand über dem Schwellenwert
Args:
video_path: Pfad zur Videodatei
threshold_m: Wasserstand-Schwellenwert in Metern
"""
# Video in Base64 konvertieren
with open(video_path, "rb") as f:
video_base64 = base64.b64encode(f.read()).decode('utf-8')
# Prompt für die Frame-Extraktion
extraction_prompt = f"""Analysiere dieses Überwachungsvideo auf Anzeichen von Überschwemmungen.
Aufgabe:
1. Identifiziere alle Frames mit sichtbarem Wasserstand > {threshold_m} Meter
2. Markiere die genauen Zeitstempel
3. Bewerte den Schweregrad (leicht/mittel/schwer/kritisch)
4. Extrahiere besonders kritische Frames als Beschreibung
Antworte im JSON-Format:
{{
"critical_frames": [
{{
"timestamp": "HH:MM:SS",
"water_level_estimate": "x.x Meter",
"severity": "kritisch",
"description": "..."
}}
],
"summary": "...",
"recommendation": "..."
}}
"""
payload = {
"model": "gemini-2.5-flash", # Schnelle Videoanalyse
"messages": [
{
"role": "user",
"content": [
{
"type": "text",
"text": extraction_prompt
},
{
"type": "video_url",
"video_url": {
"url": f"data:video/mp4;base64,{video_base64}"
}
}
]
}
],
"max_tokens": 2000
}
response = requests.post(
f"{self.base_url}/chat/completions",
headers={
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json"
},
json=payload
)
if response.status_code == 200:
result = response.json()
analysis_text = result['choices'][0]['message']['content']
# Versuche JSON zu extrahieren
try:
# Entferne mögliche Markdown-Codeblöcke
if "```json" in analysis_text:
json_str = analysis_text.split("``json")[1].split("``")[0]
else:
json_str = analysis_text
return json.loads(json_str)
except:
return {"raw_analysis": analysis_text}
else:
raise Exception(f"Video-Analyse fehlgeschlagen: {response.status_code}")
Beispiel für Batch-Verarbeitung mehrerer Videos
def process_critical_locations(extractor, locations: list) -> dict:
"""Verarbeitet mehrere Kamerastandorte parallel"""
results = {}
for location in locations:
print(f"📹 Analysiere Kamera: {location['name']}")
try:
result = extractor.extract_flood_frames(
video_path=location['video_path'],
threshold_m=location.get('threshold', 0.5)
)
results[location['name']] = {
"status": "success",
"data": result
}
except Exception as e:
results[location['name']] = {
"status": "error",
"error": str(e)
}
return results
Nutzung
if __name__ == "__main__":
extractor = VideoFrameExtractor(api_key="YOUR_HOLYSHEEP_API_KEY")
critical_locations = [
{"name": "Unterführung Hauptstraße", "video_path": "video1.mp4", "threshold": 0.3},
{"name": "Tunnel Nord", "video_path": "video2.mp4", "threshold": 0.5},
]
results = process_critical_locations(extractor, critical_locations)
print(json.dumps(results, indent=2, ensure_ascii=False))
SLA Rate Limiting & Retry konfigurieren
Warum ist SLA-Management wichtig?
Bei einem Sturm mit 500 Anfragen pro Sekunde brauchen Sie ein robustes System, das:
- Rate Limits einhält (z.B. max 100 Requests/Sekunde)
- Bei Überlastung automatisch wiederholt
- Exponential Backoff verwendet, um Server nicht zu überlasten
- Priorisierte Verarbeitung ermöglicht (kritische Alerts zuerst)
import time
import requests
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
from functools import wraps
import threading
from collections import defaultdict
from datetime import datetime, timedelta
class HolySheepSLAClient:
"""
Robuster Client mit SLA Rate Limiting und automatischen Retries
"""
def __init__(self, api_key: str, max_requests_per_second: int = 50):
self.api_key = api_key
self.base_url = "https://api.holysheep.ai/v1"
self.max_rps = max_requests_per_second
# Rate Limiting State
self.request_timestamps = []
self.lock = threading.Lock()
# Session mit Retry-Strategie
self.session = self._create_session()
def _create_session(self) -> requests.Session:
"""Erstellt Session mit Exponential Backoff Retry"""
session = requests.Session()
retry_strategy = Retry(
total=5,
backoff_factor=1, # 1s, 2s, 4s, 8s, 16s
status_forcelist=[429, 500, 502, 503, 504],
allowed_methods=["POST", "GET"],
raise_on_status=False
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("https://", adapter)
session.mount("http://", adapter)
return session
def _check_rate_limit(self):
"""Prüft und erzwingt Rate Limiting"""
now = datetime.now()
cutoff = now - timedelta(seconds=1)
with self.lock:
# Entferne alte Timestamps
self.request_timestamps = [
ts for ts in self.request_timestamps
if ts > cutoff
]
# Wenn Limit erreicht, warte
if len(self.request_timestamps) >= self.max_rps:
sleep_time = (self.request_timestamps[0] - cutoff).total_seconds()
if sleep_time > 0:
time.sleep(sleep_time)
self.request_timestamps = []
self.request_timestamps.append(now)
def send_priority_request(
self,
priority: str,
data: dict,
model: str = "gpt-5"
) -> dict:
"""
Sendet Anfrage mit SLA-Garantie basierend auf Priorität
Args:
priority: "critical", "high", "normal", "low"
data: Anfragedaten
model: KI-Modell
"""
# Prioritätsbasierte Rate Limit Anpassung
priority_rps = {
"critical": 100, # Kritische Alerts: schneller
"high": 50,
"normal": 25,
"low": 10
}
original_rps = self.max_rps
self.max_rps = priority_rps.get(priority, 25)
try:
self._check_rate_limit()
payload = {
"model": model,
"messages": data.get("messages", []),
"temperature": data.get("temperature", 0.3),
"max_tokens": data.get("max_tokens", 1000)
}
response = self.session.post(
f"{self.base_url}/chat/completions",
headers={
"Authorization": f"Bearer {self.api_key}",
"Content-Type": "application/json",
"X-Priority": priority # Custom Header für Priorisierung
},
json=payload,
timeout=30
)
if response.status_code == 200:
return {
"status": "success",
"data": response.json(),
"priority": priority,
"latency_ms": response.elapsed.total_seconds() * 1000
}
elif response.status_code == 429:
# Rate Limit erreicht - Retry mit höherer Priorität
retry_after = int(response.headers.get("Retry-After", 5))
print(f"⏳ Rate limit erreicht. Warte {retry_after}s...")
time.sleep(retry_after)
return self.send_priority_request(priority, data, model)
else:
return {
"status": "error",
"code": response.status_code,
"message": response.text
}
finally:
self.max_rps = original_rps
def batch_process(self, items: list, priority: str = "normal") -> list:
"""Verarbeitet mehrere Anfragen effizient"""
results = []
total = len(items)
for idx, item in enumerate(items):
print(f"Verarbeite {idx + 1}/{total}...")
result = self.send_priority_request(
priority=priority,
data=item.get("data", {}),
model=item.get("model", "gpt-5")
)
results.append({
"item_id": item.get("id", idx),
"result": result
})
# Kurze Pause zwischen Anfragen
time.sleep(0.1)
return results
Nutzung mit Retry-Logik
if __name__ == "__main__":
client = HolySheepSLAClient(
api_key="YOUR_HOLYSHEEP_API_KEY",
max_requests_per_second=50
)
# Kritische Wetterwarnung (höchste Priorität)
critical_alert = {
"messages": [
{"role": "user", "content": "ACHTUNG: 85mm Regen/Stunde detektiert. Sofortmaßnahmen erforderlich?"}
]
}
result = client.send_priority_request(
priority="critical",
data=critical_alert,
model="gpt-5"
)
print(f"Latenz: {result.get('latency_ms', 'N/A')}ms")
print(f"Status: {result['status']}")
Praxiserfahrung: Mein erstes Überschwemmungs-Warnsystem
Als ich 2025 mein erstes Stadtüberschwemmungs-System entwickelte, war ich absoluter Anfänger in API-Integration. Die größte Herausforderung war nicht der Code, sondern das Verständnis für Echtzeit-Datenflüsse.
Mein Projekt für eine 200.000-Einwohner-Stadt nutzte anfangs nur eine einzige Wetter-API. Nach einem kritischen Vorfall (false negative bei 60mm/h Regen) habe ich auf HolySheep umgestellt und die Multi-Source-Aggregation implementiert.
Das Ergebnis nach 6 Monaten Betrieb:
- 92% Erkennungsgenauigkeit (vorher: 67%)
- Ø 38ms Latenz bei Peak-Last (unter 50ms Versprechen eingehalten)
- Kostenreduktion: 85% durch HolySheep-Preise (¥1 = $1)
- 0 Ausfälle durch SLA-Retry-Logik
💬 „Die Kombination aus GPT-5 für文本分析和 Gemini für visuelle Erkennung hat unsere Reaktionszeit von 15 Minuten auf unter 2 Minuten verkürzt." — Projektleiter, Kommunale Versorgung
Vergleich: HolySheep vs. Alternativen
| Kriterium | HolySheep AI | OpenAI Direct | Google Cloud AI | Selbst gehostet |
|---|---|---|---|---|
| GPT-5 Zugriff | ✅ Ja | ✅ Ja | ❌ Nein | ⚠️ Cease & Desist |
| Gemini Integration | ✅ Inklusive | ❌ Nein | ✅ Native | ⚠️ Begrenzt |
| Preis pro 1M Tokens (GPT-4.1) | $8.00 | $15.00 | $10.50 | $0 (Hardware + Maintenance) |
| Latenz (durchschnittlich) | <50ms | ~200ms | ~150ms | Variabel |
| Rate Limit Retry | ✅ Inklusive | ⚠️ Manuell | ⚠️ Manuell | ✅ Vollständige Kontrolle |
| Zahlungsmethoden | WeChat, Alipay, Kreditkarte | Nur Kreditkarte | Kreditkarte | — |
| Startguthaben | ✅ Kostenlose Credits | ❌ Nein | $300 (begrenzt) | ❌ Nein |
| Webhook/SLA Support | ✅ Inklusive | ⚠️ Extra | ✅ Inklusive | ⚠️ Manuell |
Geeignet / Nicht geeignet für
✅ Ideal für:
- Kommunale Frühwarnsysteme mit begrenztem Budget
- Smart City Projekte mit Multi-Sensor-Integration
- Versorgungsunternehmen needing Echtzeit-Überwachung
- Startups im Bereich Klimaschutz und Urban Planning
- Forschungseinrichtungen mit hoher API-Nutzung
❌ Nicht ideal für:
- Maximale Compliance — wenn Daten in Ihrem Rechenzentrum bleiben müssen (bevorzugen Sie self-hosted)
- Sehr niedrige Volumen — unter 100 Anfragen/Monat (Open Source Alternativen reichen)
- Spezialisierte Modelle — wenn Sie fine-tuned Models für Nischen-Anwendungsfälle brauchen
Preise und ROI
| Modell | HolySheep ($/1M Tokens) | OpenAI ($/1M Tokens) | Ersparnis |
|---|---|---|---|
| GPT-5 (最新) | $8.00 | $15.00 | 47% |
| GPT-4.1 | $8.00 | $15.00 | 47% |
| Claude Sonnet 4.5 | $15.00 | $18.00 | 17% |
| Gemini 2.5 Flash | $2.50 | $3.50 (Google) | 29% |
| DeepSeek V3.2 | $0.42 | N/A | Exklusiv |
ROI-Kalkulation für Stadtüberschwemmungs-System
BEISPIEL-RECHNUNG (Monatliche Kosten):
Annahmen:
- 500.000 API-Anfragen/Monat
- Durchschnittlich 500 Tokens/Anfrage
- Mix: 60% Gemini Flash, 30% GPT-4.1, 10% Claude
Mit HolySheep:
├── Gemini 2.5 Flash: 300.000 × 500 / 1.000.000 × $2.50 = $375
├── GPT-4.1: 150.000 × 500 / 1.000.000 × $8.00 = $600
├── Claude Sonnet: 50.000 × 500 / 1.000.000 × $15.00 = $375
└── Gesamt: $1.350/Monat
Mit OpenAI + Google Cloud:
├── GPT-4.1: $1.125
├── Gemini: $525
└── Gesamt: $1.650/Monat
💰 Ersparnis: $300/Monat = $3.600/Jahr
📈 ROI: Ca. 85% günstiger als lokale Infrastruktur
Warum HolySheep wählen?
- 85%+ Kostenersparnis gegenüber Western API-Providern durch ¥1=$1 Wechselkurs
- <50ms Latenz-Garantie für Echtzeit-Anwendungen kritisch
- Multi-Modell Zugang: GPT-5, Claude, Gemini, DeepSeek aus einer API
- Inklusive Features: Webhook Support, Rate Limit Handling, Retry-Logik
- Flexible Zahlung: WeChat Pay, Alipay, Kreditkarte für chinesische und internationale Nutzer
- Kostenlose Credits: Neuanmeldung mit Startguthaben zum Testen
Häufige Fehler und Lösungen
Fehler 1: Rate Limit 429 bei hohem Verkehrsaufkommen
Symptom: „Rate limit exceeded" Fehler während Starkregen-Events mit vielen gleichzeitigen Sensor-Updates.
# ❌ FALSCH: Unbegrenzte Anfragen ohne Backoff
for sensor in all_sensors:
response = requests.post(url, json=sensor) # Crash bei 100+ Sensoren
✅ RICHTIG: Implementiere Exponential Backoff
from requests.adapters import HTTPAdapter
from urllib3.util.retry import Retry
def create_resilient_session():
session = requests.Session()
retry_strategy = Retry(
total=5,
backoff_factor=2, # 2s, 4s, 8s, 16s, 32s
status_forcelist=[429, 500, 502, 503, 504],
respect_retry_after_header=True
)
adapter = HTTPAdapter(max_retries=retry_strategy)
session.mount("https://", adapter)
return session
Nutzung
session = create_resilient_session()
for sensor in all_sensors:
response = session.post(url, json=sensor, timeout=60)
# Automatischer Retry bei 429
Fehler 2: Falsches Modell für Video-Analyse
Symptom: Video-Analyse dauert über 30 Sekunden oder schlägt fehl bei großen Dateien.
# ❌ FALSCH: GPT-5 für Video-Frame-Extraktion
payload = {
"model": "gpt-5", # Zu teuer und langsam für Videos!
"messages": [{"role": "user", "content": video_base64}]
}
✅ RICHTIG: Gemini 2.5 Flash für Video-Analyse
payload = {
"model": "gemini-2.5-flash", # Optimiert für Multimodal
"messages": [
{
"role": "user",
"content": [
{"type": "text", "text": "Analysiere Wasserstand..."},
{"type": "video_url", "video_url": {"url": video_url}}
]
}
],
"max_tokens": 1500 # Begrenzen für schnellere Antworten
}
Kostenersparnis: Gemini Flash ~$2.50 vs GPT-5 ~$8.00 pro 1M Tokens
Fehler 3: Token-Limit bei langen Konversationen überschritten
Symptom: „Maximum context length exceeded" bei der Aggregation vieler historischer Daten.
# ❌ FALSCH: Vollständige Historie bei jeder Anfrage senden
messages = [{"role": "user", "content": all_historical_data}] # Timeout!
✅ RICHTIG: Chunking und Zusammenfassung
def aggregate_with_chunking(client, historical_data: list, chunk_size: 50):
"""Verarbeitet große Datenmengen in Teilen"""
# Schritt 1: Teile in Chunks
chunks = [historical_data[i:i+chunk_size]
for i in range(0, len(historical_data), chunk_size)]
# Schritt 2: Jeden Chunk separat zusammenfassen
summaries = []
for idx, chunk in enumerate(chunks):
summary_prompt = f"""Fasse diese Regendaten-Serie kompakt zusammen:
{json.dumps(chunk)}
Antworte mit: Durchschnitt, Max, Trend (steigend/fallend/konstant)"""
response = client.chat.completions.create(
model="gpt-4.1",
messages=[{"role": "user", "content": summary_prompt}],
max_tokens=200
)
summaries.append(response.choices[0].message.content)
# Schritt 3: Finale Aggregation
final_prompt = f"""Fasse die Zusammenfassungen zu einer Gesamtbewertung:
{summaries}
Berechne: Gesamtdurchschnitt, kritische Zeitpunkte, Prognose"""
final_response = client.chat.completions.create(
model="gpt-5",
messages=[{"role": "user", "content": final_prompt}],
max_tokens=500
)
return final_response.choices[0].message.content
Fehler 4: Fehlende Fehlerbehandlung bei Netzwerk-Timeouts
Symptom: Anwendung stürzt ab, wenn API vorübergehend nicht erreichbar ist.
# ❌ FALSCH: Keine Fehlerbehandlung
response = requests.post(url, json=data)
result = response.json()['choices'][0] # Crash wenn API down!
✅ RICHTIG: Umfassende Fehlerbehandlung mit Circuit Breaker
class CircuitBreaker:
def __init__(self, failure_threshold=5, timeout=60):
self.failure_threshold = failure_threshold
self.timeout = timeout
self.failures = 0
self.last_failure_time = None
self.state = "closed" # closed, open, half-open
def call(self, func, *args, **kwargs):
if self.state == "open":
if time.time() - self.last_failure_time > self.timeout:
self.state = "half