"""
SalesPath — HF Spaces Keepalive App
Serves a simple FastAPI app after training completes to keep
the HF Space alive and display training results.
"""
import os
import json
from pathlib import Path
from fastapi import FastAPI
from fastapi.responses import HTMLResponse, JSONResponse
app = FastAPI(title="SalesPath — Training Complete")
OUTPUT_DIR = Path(os.environ.get("OUTPUT_DIR", "/app/salespath_out"))
@app.get("/health")
async def health():
return {"status": "ok", "service": "SalesPath Training"}
@app.get("/")
async def root():
"""Display training results page."""
html = """
SalesPath Training Complete
🏆 SalesPath Training Complete
Trained model has been uploaded to Hugging Face Hub.
"""
# Load eval results
eval_path = OUTPUT_DIR / "eval_results.json"
if eval_path.exists():
try:
eval_data = json.loads(eval_path.read_text())
html += 'Evaluation Results
'
for key, value in eval_data.items():
if isinstance(value, (int, float)):
html += f'
'
else:
html += f'
{json.dumps(value, indent=2)}'
html += "
"
except Exception:
pass
# Show reward graph
graph_path = OUTPUT_DIR / "reward_graph.png"
if graph_path.exists():
import base64
img_b64 = base64.b64encode(graph_path.read_bytes()).decode()
html += f'Reward Curve

'
# Show reward history stats
history_path = OUTPUT_DIR / "reward_history.txt"
if history_path.exists():
lines = history_path.read_text().strip().splitlines()
rewards = [float(line.split("\t")[-1]) for line in lines if line.strip()]
if rewards:
html += f"""
Training Stats
{sum(rewards)/len(rewards):.4f}
Mean Reward
{max(rewards):.4f}
Max Reward
{min(rewards):.4f}
Min Reward
"""
html += """
Next Steps
1. View model on Hugging Face Hub
2. Run inference with the trained model
3. Stop this Space to avoid billing
"""
return HTMLResponse(html)
@app.get("/api/results")
async def api_results():
"""Return training results as JSON."""
results = {}
eval_path = OUTPUT_DIR / "eval_results.json"
if eval_path.exists():
try:
results["eval"] = json.loads(eval_path.read_text())
except Exception:
pass
history_path = OUTPUT_DIR / "reward_history.txt"
if history_path.exists():
lines = history_path.read_text().strip().splitlines()
rewards = [float(line.split("\t")[-1]) for line in lines if line.strip()]
if rewards:
results["training"] = {
"episodes": len(rewards),
"mean_reward": sum(rewards) / len(rewards),
"max_reward": max(rewards),
"min_reward": min(rewards),
"std_reward": __import__("statistics").stdev(rewards) if len(rewards) > 1 else 0,
}
return JSONResponse(results)