JacekAI / HUGGINGFACE_FIX.md
Jacek Zadrożny
Lazy loading
59c860e
# Hugging Face Lazy Initialization Fix
## Problem
Aplikacja na Hugging Face Spaces nie uruchamiała się, ponieważ czas inicjalizacji bazy danych i agenta przekraczał timeout HF (zazwyczaj ~60 sekund).
## Rozwiązanie
Zaimplementowano **leniwą inicjalizację** (lazy loading):
### 1. **Gradio uruchamia się NATYCHMIAST**
- Aplikacja Gradio startuje w <1 sekundę
- HF Spaces widzi działającą aplikację i nie pokazuje timeoutu
### 2. **Agent inicjalizuje się W TLE** 🔄
- Tworzenie agenta i połączenie z bazą danych następuje w osobnym wątku
- Użytkownik widzi status inicjalizacji na żywo
### 3. **Pierwsze zapytania czekają na gotowość**
- Jeśli użytkownik spróbuje zadać pytanie przed gotowością agenta
- Aplikacja pokazuje komunikat "Agent is initializing, please wait..."
- Po gotowości agenta odpowiedź jest generowana normalnie
## Zmiany w kodzie
### `app.py` - Główne zmiany:
```python
# Zmienne stanu agenta
agent_instance: A11yExpertAgent = None
agent_ready = False
agent_error = None
# Inicjalizacja w osobnym wątku
def initialize_agent_background():
"""Initialize the agent in background thread."""
global agent_instance, agent_ready, agent_error, loop
try:
logger.info("🔄 Starting agent initialization in background...")
loop = asyncio.new_event_loop()
asyncio.set_event_loop(loop)
agent_instance = loop.run_until_complete(create_agent())
agent_ready = True
logger.success("✅ A11y Expert Agent is ready!")
except Exception as e:
logger.error(f"❌ Failed to initialize agent: {e}")
agent_error = str(e)
agent_instance = None
# Start w tle przy uruchomieniu
if __name__ == "__main__":
init_thread = threading.Thread(target=initialize_agent_background, daemon=True)
init_thread.start()
demo.launch(...)
```
### Wskaźnik statusu w UI:
```python
# Status indicator pokazujący czy agent jest gotowy
status_box = gr.Markdown("⏳ **Status:** Agent is initializing in background...")
def check_status():
if agent_ready:
return "✅ **Status:** Agent ready!"
elif agent_error:
return f"❌ **Status:** Agent failed - {agent_error}"
else:
return "⏳ **Status:** Agent is initializing in background..."
# Auto-update co 2 sekundy
demo.load(lambda: None, None, None).then(
check_status, outputs=status_box, every=2
)
```
### Oczekiwanie na gotowość w `respond()`:
```python
async def respond(message: str, history: list[list[str]]):
# Czekaj aż agent będzie gotowy
if not agent_ready:
if agent_error:
yield f"❌ Agent initialization failed: {agent_error}"
return
yield "⏳ Agent is initializing, please wait..."
# Czekaj do 120 sekund
for i in range(120):
await asyncio.sleep(1)
if agent_ready:
break
if agent_error:
yield f"❌ Agent initialization failed: {agent_error}"
return
if not agent_ready:
yield "❌ Agent initialization timeout. Please refresh and try again."
return
# Normalna generacja odpowiedzi
async for chunk in agent_instance.ask(message):
full_response += chunk
yield full_response
```
## Korzyści
**Błyskawiczny start** - Gradio uruchamia się w <1s
**Brak timeoutu na HF** - HF widzi działającą aplikację
**Przejrzystość** - Użytkownik widzi status inicjalizacji
**Graceful handling** - Obsługa błędów inicjalizacji
**Zachowanie funkcjonalności** - Po gotowości działa normalnie
## Deployment na Hugging Face
1. Push zmian do repo
2. HF Space automatycznie zbuduje i uruchomi aplikację
3. Aplikacja wystartuje natychmiast (bez timeoutu!)
4. Agent załaduje się w tle w ciągu ~30-60 sekund
5. Status będzie aktualizowany na żywo w UI
## Testowanie lokalne
```bash
python app.py
```
Powinieneś zobaczyć:
```
🚀 Starting Gradio app with lazy agent initialization...
Launching Gradio interface...
🔄 Starting agent initialization in background...
Running on local URL: http://127.0.0.1:7860
✅ A11y Expert Agent is ready!
```
## Backup
Stary plik zapisany jako: `app_old.py`