Spaces:
Sleeping
Sleeping
fix: mount gradio on fastapi directly
Browse files
app.py
CHANGED
|
@@ -655,29 +655,16 @@ def verify_claim():
|
|
| 655 |
init_db() # Ensure DB exists before accepting requests
|
| 656 |
load_models()
|
| 657 |
|
| 658 |
-
# βββ Gradio + Flask Integration via
|
| 659 |
-
#
|
| 660 |
-
#
|
| 661 |
-
# This avoids all WSGIMiddleware path-stripping conflicts with HF's Gradio proxy.
|
| 662 |
try:
|
| 663 |
-
import threading
|
| 664 |
-
import httpx
|
| 665 |
import gradio as gr
|
| 666 |
import spaces
|
| 667 |
-
from fastapi import
|
| 668 |
-
from fastapi.
|
| 669 |
|
| 670 |
-
# ββ 1.
|
| 671 |
-
_FLASK_PORT = 7861
|
| 672 |
-
|
| 673 |
-
def _run_flask_internal():
|
| 674 |
-
logger.info(f"Starting internal Flask server on port {_FLASK_PORT}...")
|
| 675 |
-
app.run(host='127.0.0.1', port=_FLASK_PORT, debug=False, use_reloader=False)
|
| 676 |
-
|
| 677 |
-
_flask_thread = threading.Thread(target=_run_flask_internal, daemon=True)
|
| 678 |
-
_flask_thread.start()
|
| 679 |
-
|
| 680 |
-
# ββ 2. Gradio UI βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
| 681 |
@spaces.GPU
|
| 682 |
def predict_gradio(statement, model_type):
|
| 683 |
if not statement or len(statement) < 5:
|
|
@@ -715,58 +702,22 @@ try:
|
|
| 715 |
],
|
| 716 |
outputs="text",
|
| 717 |
title="Truth Detector API & Interactive Demo",
|
| 718 |
-
description="Backend API for Fake News Detection. REST API available at /
|
| 719 |
)
|
| 720 |
|
| 721 |
-
# ββ
|
| 722 |
-
|
| 723 |
-
|
| 724 |
-
|
| 725 |
-
|
| 726 |
-
|
| 727 |
-
|
| 728 |
-
|
| 729 |
-
|
| 730 |
-
|
| 731 |
-
|
| 732 |
-
|
| 733 |
-
|
| 734 |
-
body = await request.body()
|
| 735 |
-
|
| 736 |
-
fwd_headers = {
|
| 737 |
-
k: v for k, v in request.headers.items()
|
| 738 |
-
if k.lower() not in _SKIP_HEADERS
|
| 739 |
-
}
|
| 740 |
-
|
| 741 |
-
try:
|
| 742 |
-
async with httpx.AsyncClient(timeout=60) as client:
|
| 743 |
-
resp = await client.request(
|
| 744 |
-
method=request.method,
|
| 745 |
-
url=target_url,
|
| 746 |
-
headers=fwd_headers,
|
| 747 |
-
content=body,
|
| 748 |
-
params=dict(request.query_params),
|
| 749 |
-
follow_redirects=True,
|
| 750 |
-
)
|
| 751 |
-
resp_headers = {
|
| 752 |
-
k: v for k, v in resp.headers.items()
|
| 753 |
-
if k.lower() not in _SKIP_HEADERS
|
| 754 |
-
}
|
| 755 |
-
return _FastAPIResponse(
|
| 756 |
-
content=resp.content,
|
| 757 |
-
status_code=resp.status_code,
|
| 758 |
-
headers=resp_headers,
|
| 759 |
-
)
|
| 760 |
-
except Exception as proxy_err:
|
| 761 |
-
logger.error(f"Proxy error for {request.url.path}: {proxy_err}")
|
| 762 |
-
return _FastAPIResponse(
|
| 763 |
-
content=b'{"error":"Backend proxy error","detail":"' + str(proxy_err).encode() + b'"}',
|
| 764 |
-
status_code=502,
|
| 765 |
-
headers={"Content-Type": "application/json"},
|
| 766 |
-
)
|
| 767 |
-
|
| 768 |
-
# If not /backend/*, let Gradio handle it normally
|
| 769 |
-
return await call_next(request)
|
| 770 |
|
| 771 |
_GRADIO_AVAILABLE = True
|
| 772 |
|
|
@@ -777,7 +728,9 @@ except ImportError as _ie:
|
|
| 777 |
if __name__ == '__main__':
|
| 778 |
port = int(os.environ.get('PORT', 7860))
|
| 779 |
if _GRADIO_AVAILABLE:
|
| 780 |
-
|
|
|
|
|
|
|
| 781 |
else:
|
| 782 |
app.run(host='0.0.0.0', port=port, debug=False)
|
| 783 |
|
|
|
|
| 655 |
init_db() # Ensure DB exists before accepting requests
|
| 656 |
load_models()
|
| 657 |
|
| 658 |
+
# βββ Gradio + Flask Integration via FastAPI mount ββββββββββββββββββββββββββββββ
|
| 659 |
+
# The official way to combine Gradio and custom APIs in HF Spaces is to create
|
| 660 |
+
# a FastAPI app, mount the custom API, and then mount Gradio on top.
|
|
|
|
| 661 |
try:
|
|
|
|
|
|
|
| 662 |
import gradio as gr
|
| 663 |
import spaces
|
| 664 |
+
from fastapi import FastAPI
|
| 665 |
+
from fastapi.middleware.wsgi import WSGIMiddleware
|
| 666 |
|
| 667 |
+
# ββ 1. Gradio UI βββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 668 |
@spaces.GPU
|
| 669 |
def predict_gradio(statement, model_type):
|
| 670 |
if not statement or len(statement) < 5:
|
|
|
|
| 702 |
],
|
| 703 |
outputs="text",
|
| 704 |
title="Truth Detector API & Interactive Demo",
|
| 705 |
+
description="Backend API for Fake News Detection. REST API available at /api/*"
|
| 706 |
)
|
| 707 |
|
| 708 |
+
# ββ 2. Create master FastAPI app βββββββββββββββββββββββββββββββββββββββββ
|
| 709 |
+
# We rename the existing Flask app to flask_app, and create a new FastAPI app
|
| 710 |
+
# named `app` because Hugging Face will automatically run the variable named `app`.
|
| 711 |
+
flask_app = app
|
| 712 |
+
app = FastAPI()
|
| 713 |
+
|
| 714 |
+
# Mount Flask API routes at /api/ (This handles /api/predict, /api/auth/*, etc.)
|
| 715 |
+
# Flask routes internally start with /api (e.g. @app.route('/api/health')),
|
| 716 |
+
# so we mount it at root "/" so that /api/health goes straight to Flask's /api/health
|
| 717 |
+
app.mount("/flask", WSGIMiddleware(flask_app))
|
| 718 |
+
|
| 719 |
+
# Mount Gradio app at root
|
| 720 |
+
app = gr.mount_gradio_app(app, demo, path="/")
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 721 |
|
| 722 |
_GRADIO_AVAILABLE = True
|
| 723 |
|
|
|
|
| 728 |
if __name__ == '__main__':
|
| 729 |
port = int(os.environ.get('PORT', 7860))
|
| 730 |
if _GRADIO_AVAILABLE:
|
| 731 |
+
# For local testing, run the master FastAPI app with Uvicorn
|
| 732 |
+
import uvicorn
|
| 733 |
+
uvicorn.run(app, host="0.0.0.0", port=port)
|
| 734 |
else:
|
| 735 |
app.run(host='0.0.0.0', port=port, debug=False)
|
| 736 |
|