Spaces:
Sleeping
Sleeping
Fix LLM API keys not loaded from HF Spaces secrets
Browse files- Remove .env.example copy in Dockerfile that overwrote HF Spaces secrets
- Add startup logging to show which LLM providers are available
- Add LLM provider status to /health endpoint for debugging
🤖 Generated with [Claude Code](https://claude.com/claude-code)
Co-Authored-By: Claude Opus 4.5 <noreply@anthropic.com>
- Dockerfile +2 -1
- src/api/app.py +22 -3
Dockerfile
CHANGED
|
@@ -13,7 +13,8 @@ RUN pip install --no-cache-dir -r requirements.txt
|
|
| 13 |
COPY src/ ./src/
|
| 14 |
COPY a2a/ ./a2a/
|
| 15 |
COPY data/ ./data/
|
| 16 |
-
|
|
|
|
| 17 |
|
| 18 |
# Copy pre-built frontend (built locally and committed)
|
| 19 |
COPY static/ ./static/
|
|
|
|
| 13 |
COPY src/ ./src/
|
| 14 |
COPY a2a/ ./a2a/
|
| 15 |
COPY data/ ./data/
|
| 16 |
+
# Note: Don't copy .env file - HF Spaces injects secrets as environment variables
|
| 17 |
+
# .env.example is for local development only
|
| 18 |
|
| 19 |
# Copy pre-built frontend (built locally and committed)
|
| 20 |
COPY static/ ./static/
|
src/api/app.py
CHANGED
|
@@ -8,14 +8,26 @@ from pathlib import Path
|
|
| 8 |
from fastapi import FastAPI
|
| 9 |
from fastapi.middleware.cors import CORSMiddleware
|
| 10 |
from fastapi.staticfiles import StaticFiles
|
|
|
|
| 11 |
from dotenv import load_dotenv
|
| 12 |
|
| 13 |
from src.api.routes.analysis import router as analysis_router
|
| 14 |
from src.api.routes.stocks import router as stocks_router, load_stock_listings
|
| 15 |
from src.services.workflow_store import WORKFLOWS
|
| 16 |
|
| 17 |
-
# Load environment variables
|
| 18 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 19 |
|
| 20 |
app = FastAPI(
|
| 21 |
title="Instant SWOT Agent API",
|
|
@@ -52,9 +64,16 @@ async def startup_event():
|
|
| 52 |
@app.get("/health")
|
| 53 |
async def health_check():
|
| 54 |
"""Health check endpoint."""
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 55 |
return {
|
| 56 |
"status": "ok",
|
| 57 |
-
"active_workflows": len(WORKFLOWS)
|
|
|
|
|
|
|
| 58 |
}
|
| 59 |
|
| 60 |
|
|
|
|
| 8 |
from fastapi import FastAPI
|
| 9 |
from fastapi.middleware.cors import CORSMiddleware
|
| 10 |
from fastapi.staticfiles import StaticFiles
|
| 11 |
+
import os
|
| 12 |
from dotenv import load_dotenv
|
| 13 |
|
| 14 |
from src.api.routes.analysis import router as analysis_router
|
| 15 |
from src.api.routes.stocks import router as stocks_router, load_stock_listings
|
| 16 |
from src.services.workflow_store import WORKFLOWS
|
| 17 |
|
| 18 |
+
# Load environment variables from .env file (for local development)
|
| 19 |
+
# In HF Spaces, secrets are injected as environment variables automatically
|
| 20 |
+
load_dotenv() # Safe to call even if .env doesn't exist
|
| 21 |
+
|
| 22 |
+
# Debug: Log which LLM providers are available (without exposing keys)
|
| 23 |
+
_llm_providers = []
|
| 24 |
+
if os.getenv("GROQ_API_KEY"):
|
| 25 |
+
_llm_providers.append("Groq")
|
| 26 |
+
if os.getenv("GEMINI_API_KEY"):
|
| 27 |
+
_llm_providers.append("Gemini")
|
| 28 |
+
if os.getenv("OPENROUTER_API_KEY"):
|
| 29 |
+
_llm_providers.append("OpenRouter")
|
| 30 |
+
print(f"[Startup] LLM providers available: {_llm_providers or 'NONE - check HF Spaces secrets!'}")
|
| 31 |
|
| 32 |
app = FastAPI(
|
| 33 |
title="Instant SWOT Agent API",
|
|
|
|
| 64 |
@app.get("/health")
|
| 65 |
async def health_check():
|
| 66 |
"""Health check endpoint."""
|
| 67 |
+
llm_status = {
|
| 68 |
+
"groq": bool(os.getenv("GROQ_API_KEY")),
|
| 69 |
+
"gemini": bool(os.getenv("GEMINI_API_KEY")),
|
| 70 |
+
"openrouter": bool(os.getenv("OPENROUTER_API_KEY")),
|
| 71 |
+
}
|
| 72 |
return {
|
| 73 |
"status": "ok",
|
| 74 |
+
"active_workflows": len(WORKFLOWS),
|
| 75 |
+
"llm_providers_configured": llm_status,
|
| 76 |
+
"llm_available": any(llm_status.values())
|
| 77 |
}
|
| 78 |
|
| 79 |
|