waliullah123 commited on
Commit
a24f791
Β·
verified Β·
1 Parent(s): 1d1cedf

fix: use threading+httpx proxy instead of WSGIMiddleware mount

Browse files
Files changed (1) hide show
  1. app.py +65 -9
app.py CHANGED
@@ -655,14 +655,29 @@ def verify_claim():
655
  init_db() # Ensure DB exists before accepting requests
656
  load_models()
657
 
658
- # ─── Optional Gradio Interface (only when Gradio SDK is available) ────────────
659
- # In Docker mode (our HF deployment), Gradio is NOT installed and we serve
660
- # Flask directly via gunicorn. This block is kept for legacy compatibility.
 
661
  try:
 
 
662
  import gradio as gr
663
  import spaces
664
- from fastapi.middleware.wsgi import WSGIMiddleware
 
665
 
 
 
 
 
 
 
 
 
 
 
 
666
  @spaces.GPU
667
  def predict_gradio(statement, model_type):
668
  if not statement or len(statement) < 5:
@@ -700,13 +715,55 @@ try:
700
  ],
701
  outputs="text",
702
  title="Truth Detector API & Interactive Demo",
703
- description="Backend API for Fake News Detection. REST API endpoints available at /api/*"
 
 
 
 
 
 
 
 
704
  )
705
- demo.app.mount("/flask", WSGIMiddleware(app))
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
706
  _GRADIO_AVAILABLE = True
707
- except ImportError:
 
708
  _GRADIO_AVAILABLE = False
709
- logger.info("Gradio not available β€” running in Flask-only (Docker) mode.")
710
 
711
  if __name__ == '__main__':
712
  port = int(os.environ.get('PORT', 7860))
@@ -715,4 +772,3 @@ if __name__ == '__main__':
715
  else:
716
  app.run(host='0.0.0.0', port=port, debug=False)
717
 
718
-
 
655
  init_db() # Ensure DB exists before accepting requests
656
  load_models()
657
 
658
+ # ─── Gradio + Flask Integration via Thread Proxy ──────────────────────────────
659
+ # Flask runs on internal port 7861. Gradio exposes it via a FastAPI proxy route
660
+ # at /backend/{path}, which forwards to http://127.0.0.1:7861/{path}.
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 Request as _FastAPIRequest
668
+ from fastapi.responses import Response as _FastAPIResponse
669
 
670
+ # ── 1. Start Flask on internal port 7861 ─────────────────────────────────
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
  ],
716
  outputs="text",
717
  title="Truth Detector API & Interactive Demo",
718
+ description="Backend API for Fake News Detection. REST API available at /backend/api/*"
719
+ )
720
+
721
+ # ── 3. FastAPI proxy: /backend/{path} β†’ Flask on 127.0.0.1:7861/{path} ──
722
+ _SKIP_HEADERS = {'host', 'content-length', 'transfer-encoding', 'content-encoding'}
723
+
724
+ @demo.app.api_route(
725
+ "/backend/{path:path}",
726
+ methods=["GET", "POST", "PUT", "DELETE", "OPTIONS", "HEAD", "PATCH"]
727
  )
728
+ async def flask_proxy(request: _FastAPIRequest, path: str):
729
+ """Transparent proxy forwarding /backend/* β†’ internal Flask server."""
730
+ target_url = f"http://127.0.0.1:{_FLASK_PORT}/{path}"
731
+ fwd_headers = {
732
+ k: v for k, v in request.headers.items()
733
+ if k.lower() not in _SKIP_HEADERS
734
+ }
735
+ try:
736
+ async with httpx.AsyncClient(timeout=60) as client:
737
+ resp = await client.request(
738
+ method=request.method,
739
+ url=target_url,
740
+ headers=fwd_headers,
741
+ content=await request.body(),
742
+ params=dict(request.query_params),
743
+ follow_redirects=True,
744
+ )
745
+ resp_headers = {
746
+ k: v for k, v in resp.headers.items()
747
+ if k.lower() not in _SKIP_HEADERS
748
+ }
749
+ return _FastAPIResponse(
750
+ content=resp.content,
751
+ status_code=resp.status_code,
752
+ headers=resp_headers,
753
+ )
754
+ except Exception as proxy_err:
755
+ logger.error(f"Proxy error for /{path}: {proxy_err}")
756
+ return _FastAPIResponse(
757
+ content=b'{"error":"Backend proxy error","detail":"' + str(proxy_err).encode() + b'"}',
758
+ status_code=502,
759
+ headers={"Content-Type": "application/json"},
760
+ )
761
+
762
  _GRADIO_AVAILABLE = True
763
+
764
+ except ImportError as _ie:
765
  _GRADIO_AVAILABLE = False
766
+ logger.info(f"Gradio not available ({_ie}) β€” running in Flask-only (Docker) mode.")
767
 
768
  if __name__ == '__main__':
769
  port = int(os.environ.get('PORT', 7860))
 
772
  else:
773
  app.run(host='0.0.0.0', port=port, debug=False)
774