Update app.py
Browse files
app.py
CHANGED
|
@@ -2,11 +2,12 @@
|
|
| 2 |
import logging
|
| 3 |
import uuid
|
| 4 |
from datetime import datetime, timezone
|
| 5 |
-
from typing import Dict,
|
| 6 |
|
| 7 |
from fastapi import FastAPI
|
| 8 |
from fastapi.middleware.cors import CORSMiddleware
|
| 9 |
from fastapi.openapi.docs import get_swagger_ui_html, get_redoc_html
|
|
|
|
| 10 |
from pydantic import BaseModel
|
| 11 |
import gradio as gr
|
| 12 |
|
|
@@ -137,10 +138,7 @@ async def record_outcome(decision_id: str, success: bool):
|
|
| 137 |
return {"status": "ok", "decision_id": decision_id, "outcome": dec["outcome"]}
|
| 138 |
return {"error": "decision not found"}
|
| 139 |
|
| 140 |
-
# ========================= GRADIO UI
|
| 141 |
-
# Gradio interface will be served at the root path ("/").
|
| 142 |
-
# The FastAPI app is mounted under the "/api" subpath.
|
| 143 |
-
|
| 144 |
def get_risk_snapshot():
|
| 145 |
try:
|
| 146 |
intent = _DemoIntent()
|
|
@@ -218,34 +216,30 @@ with gr.Blocks(title="ARF v4 Demo") as demo:
|
|
| 218 |
memory_btn.click(fn=get_memory_snapshot, outputs=memory_output)
|
| 219 |
history_btn.click(fn=lambda: decision_history[-10:], outputs=decision_output)
|
| 220 |
|
| 221 |
-
# ========================= Mount
|
| 222 |
-
#
|
| 223 |
-
# The resulting `app` is a FastAPI application that serves both:
|
| 224 |
-
# - The API at `/api` (and its subpaths)
|
| 225 |
-
# - The Gradio UI at the root `/`
|
| 226 |
app = gr.mount_gradio_app(fastapi_app, demo, path="/api")
|
| 227 |
|
| 228 |
-
#
|
| 229 |
-
|
| 230 |
-
# We manually add routes to serve Swagger UI and ReDoc at /api/docs and /api/redoc,
|
| 231 |
-
# pointing to the OpenAPI schema from the mounted app.
|
| 232 |
-
@app.get("/api/docs", include_in_schema=False)
|
| 233 |
async def swagger_ui():
|
| 234 |
return get_swagger_ui_html(
|
| 235 |
-
openapi_url="/
|
| 236 |
title="ARF API Docs"
|
| 237 |
)
|
| 238 |
|
| 239 |
-
@app.get("/
|
| 240 |
async def redoc_ui():
|
| 241 |
return get_redoc_html(
|
| 242 |
-
openapi_url="/
|
| 243 |
title="ARF API ReDoc"
|
| 244 |
)
|
| 245 |
|
| 246 |
-
@app.get("/
|
| 247 |
async def openapi():
|
| 248 |
return fastapi_app.openapi()
|
| 249 |
|
| 250 |
-
#
|
| 251 |
-
|
|
|
|
|
|
|
|
|
| 2 |
import logging
|
| 3 |
import uuid
|
| 4 |
from datetime import datetime, timezone
|
| 5 |
+
from typing import Dict, Optional
|
| 6 |
|
| 7 |
from fastapi import FastAPI
|
| 8 |
from fastapi.middleware.cors import CORSMiddleware
|
| 9 |
from fastapi.openapi.docs import get_swagger_ui_html, get_redoc_html
|
| 10 |
+
from fastapi.responses import RedirectResponse
|
| 11 |
from pydantic import BaseModel
|
| 12 |
import gradio as gr
|
| 13 |
|
|
|
|
| 138 |
return {"status": "ok", "decision_id": decision_id, "outcome": dec["outcome"]}
|
| 139 |
return {"error": "decision not found"}
|
| 140 |
|
| 141 |
+
# ========================= GRADIO UI =========================
|
|
|
|
|
|
|
|
|
|
| 142 |
def get_risk_snapshot():
|
| 143 |
try:
|
| 144 |
intent = _DemoIntent()
|
|
|
|
| 216 |
memory_btn.click(fn=get_memory_snapshot, outputs=memory_output)
|
| 217 |
history_btn.click(fn=lambda: decision_history[-10:], outputs=decision_output)
|
| 218 |
|
| 219 |
+
# ========================= Mount Gradio and Add Documentation Routes =========================
|
| 220 |
+
# Mount Gradio at "/api" – this means Gradio will handle all requests starting with "/api".
|
|
|
|
|
|
|
|
|
|
| 221 |
app = gr.mount_gradio_app(fastapi_app, demo, path="/api")
|
| 222 |
|
| 223 |
+
# Add documentation routes at "/docs" (outside the Gradio mount path) to avoid conflict.
|
| 224 |
+
@app.get("/docs", include_in_schema=False)
|
|
|
|
|
|
|
|
|
|
| 225 |
async def swagger_ui():
|
| 226 |
return get_swagger_ui_html(
|
| 227 |
+
openapi_url="/openapi.json",
|
| 228 |
title="ARF API Docs"
|
| 229 |
)
|
| 230 |
|
| 231 |
+
@app.get("/redoc", include_in_schema=False)
|
| 232 |
async def redoc_ui():
|
| 233 |
return get_redoc_html(
|
| 234 |
+
openapi_url="/openapi.json",
|
| 235 |
title="ARF API ReDoc"
|
| 236 |
)
|
| 237 |
|
| 238 |
+
@app.get("/openapi.json", include_in_schema=False)
|
| 239 |
async def openapi():
|
| 240 |
return fastapi_app.openapi()
|
| 241 |
|
| 242 |
+
# Optional redirect from /api/docs to /docs for backward compatibility.
|
| 243 |
+
@app.get("/api/docs", include_in_schema=False)
|
| 244 |
+
async def redirect_docs():
|
| 245 |
+
return RedirectResponse(url="/docs")
|