josephrw's picture
Upload folder using huggingface_hub
c4916b2 verified
Raw
History Blame Contribute Delete
4.22 kB
import qrcode
import io
import base64
from datetime import datetime
from fastapi import Request
from fastapi.templating import Jinja2Templates
from fastapi.responses import HTMLResponse
from app.config import Settings
from app.session_store import create_session, get_session
from app.security import create_worker_join_token
# Use a simple in-memory template for v1; Jinja2 templates directory if present
templates = Jinja2Templates(directory="app/templates")
def render_home(request: Request) -> HTMLResponse:
return HTMLResponse(content=_home_html(), status_code=200)
def render_worker_page(request: Request, session_id: str, token: str) -> HTMLResponse:
return HTMLResponse(content=_worker_html(session_id, token), status_code=200)
def render_session_dashboard(request: Request, session_id: str) -> HTMLResponse:
session = get_session(session_id)
if not session:
return HTMLResponse(content="<h1>Session not found</h1>", status_code=404)
public_url = Settings.get_public_url()
worker_url = f"{public_url}/worker?session_id={session_id}&token={session.secret}"
qr_b64 = make_worker_qr_code(worker_url)
html = _dashboard_html(session_id, worker_url, qr_b64)
return HTMLResponse(content=html, status_code=200)
def make_worker_qr_code(worker_join_url: str) -> str:
img = qrcode.make(worker_join_url)
buf = io.BytesIO()
img.save(buf, format="PNG")
buf.seek(0)
return base64.b64encode(buf.read()).decode()
def make_api_example(session_id: str) -> dict:
public_url = Settings.get_public_url()
return {
"create_job": f"POST {public_url}/api/session/{session_id}/job",
"get_job": f"GET {public_url}/api/job/{{job_id}}",
"get_receipt": f"GET {public_url}/api/receipt/{{receipt_id}}",
}
def _home_html() -> str:
return """<!DOCTYPE html>
<html>
<head><title>PhoneGPU Space</title>
<style>
body{font-family:sans-serif;max-width:800px;margin:40px auto;padding:0 20px}
button{padding:12px 24px;font-size:16px;cursor:pointer;border-radius:6px;border:none;background:#2563eb;color:#fff}
.code{background:#f3f4f6;padding:12px;border-radius:6px;font-family:monospace;overflow:auto}
</style></head>
<body>
<h1>PhoneGPU Space</h1>
<p>Turn an iPhone into a temporary private ML compute worker.</p>
<button onclick="createSession()">Create Session</button>
<div id="output"></div>
<script>
async function createSession(){
const r=await fetch('/api/session',{method:'POST',headers:{'Content-Type':'application/json'},body:JSON.stringify({})});
const j=await r.json();
document.getElementById('output').innerHTML='<p>Session: <b>'+j.session_id+'</b></p><p>Scan QR with iPhone:</p><img src="data:image/png;base64,'+j.qr+'"><p><a href="/dashboard/'+j.session_id+'">Open Dashboard</a></p>';
}
</script>
</body></html>"""
def _worker_html(session_id: str, token: str) -> str:
# This redirects to the static worker.html with query params
return f"""<!DOCTYPE html>
<html><head><meta name="viewport" content="width=device-width, initial-scale=1">
<title>PhoneGPU Worker</title></head>
<body>
<script>window.WORKER_SESSION_ID='{session_id}';window.WORKER_TOKEN='{token}';</script>
<script>window.location.href='/static/worker.html?session_id={session_id}&token={token}';</script>
</body></html>"""
def _dashboard_html(session_id: str, worker_url: str, qr_b64: str) -> str:
return f"""<!DOCTYPE html>
<html><head><meta name="viewport" content="width=device-width, initial-scale=1">
<title>Session Dashboard</title>
<style>
body{{font-family:sans-serif;max-width:800px;margin:40px auto;padding:0 20px}}
.card{{border:1px solid #e5e7eb;border-radius:8px;padding:16px;margin:12px 0}}
</style></head>
<body>
<h1>Session Dashboard</h1>
<p>Session: <code>{session_id}</code></p>
<div class="card">
<h3>Connect iPhone</h3>
<p>Scan this QR code with your iPhone camera:</p>
<img src="data:image/png;base64,{qr_b64}" width="200">
<p>Or open: <a href="{worker_url}" target="_blank">{worker_url}</a></p>
</div>
<div class="card">
<h3>API</h3>
<p><code>POST /api/session/{session_id}/job</code></p>
<p><code>GET /api/job/{{job_id}}</code></p>
<p><code>GET /api/receipt/{{receipt_id}}</code></p>
</div>
</body></html>"""