File size: 1,459 Bytes
a62cfd3 68385f9 a62cfd3 9cb1768 a62cfd3 68385f9 2d88665 68385f9 a62cfd3 92499c3 a62cfd3 9cb1768 73a3de2 92499c3 | 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 17 18 19 20 21 22 23 24 25 26 27 28 29 30 31 32 33 34 35 36 37 38 39 40 41 42 43 44 45 46 47 48 49 50 51 52 53 | import os
import spaces
import gradio as gr
import torch
from fastapi.staticfiles import StaticFiles
from starlette.responses import FileResponse
from starlette.routing import Route
FRONTEND = os.path.join(os.path.dirname(os.path.abspath(__file__)), "frontend")
@spaces.GPU(duration=30)
def infer(x):
return f"cuda available: {torch.cuda.is_available()}, got: {x}"
with gr.Blocks() as demo:
inp, out = gr.Textbox(), gr.Textbox()
gr.Button("Run").click(infer, inp, out, api_name="infer")
demo.queue()
# demo.launch() is the officially documented ZeroGPU entrypoint — its
# startup hook is what registers @spaces.GPU functions. We keep it (rather
# than gr.mount_gradio_app on our own FastAPI instance) and instead attach
# custom routes/static files onto the live app it hands back.
app, _local_url, _share_url = demo.launch(
server_name="0.0.0.0",
server_port=7860,
prevent_thread_lock=True,
)
@app.get("/api/health")
def health():
return {"status": "ok"}
app.mount("/static", StaticFiles(directory=FRONTEND), name="static")
async def index(request):
return FileResponse(os.path.join(FRONTEND, "index.html"))
# Starlette returns the first matching route and Gradio registered its own "/"
# during launch(), so inserting ahead of it hands the root URL to our UI.
# Gradio's API routes stay intact — it just becomes an invisible GPU engine.
app.router.routes.insert(0, Route("/", index))
demo.block_thread()
|