11import logging
22import os
33from pathlib import Path
4+ from typing import Any , MutableMapping
45
5- from fastapi .exception_handlers import http_exception_handler
66import httpx
7- import orjson
8- from fastapi import FastAPI , Form , UploadFile
7+ from fastapi import FastAPI
8+ from fastapi . exception_handlers import http_exception_handler
99from fastapi .exceptions import HTTPException
10+ from fastapi .responses import FileResponse
1011from fastapi .staticfiles import StaticFiles
12+ from starlette .responses import Response
1113
12- import app .storage as storage
1314from app .api import router as api_router
14- from app .auth .handlers import AuthedUser
1515from app .lifespan import lifespan
16- from app .upload import convert_ingestion_input_to_blob , ingest_runnable
1716
1817logger = logging .getLogger (__name__ )
1918
@@ -31,41 +30,29 @@ async def httpx_http_status_error_handler(request, exc: httpx.HTTPStatusError):
3130ROOT = Path (__file__ ).parent .parent
3231
3332
34- app .include_router (api_router )
35-
33+ @app .get ("/ok" )
34+ async def ok ():
35+ return {"ok" : True }
3636
37- @app .post ("/ingest" , description = "Upload files to the given assistant." )
38- async def ingest_files (
39- files : list [UploadFile ], user : AuthedUser , config : str = Form (...)
40- ) -> None :
41- """Ingest a list of files."""
42- config = orjson .loads (config )
4337
44- assistant_id = config ["configurable" ].get ("assistant_id" )
45- if assistant_id is not None :
46- assistant = await storage .get_assistant (user ["user_id" ], assistant_id )
47- if assistant is None :
48- raise HTTPException (status_code = 404 , detail = "Assistant not found." )
38+ app .include_router (api_router , prefix = "/api" )
4939
50- thread_id = config ["configurable" ].get ("thread_id" )
51- if thread_id is not None :
52- thread = await storage .get_thread (user ["user_id" ], thread_id )
53- if thread is None :
54- raise HTTPException (status_code = 404 , detail = "Thread not found." )
55-
56- file_blobs = [convert_ingestion_input_to_blob (file ) for file in files ]
57- return ingest_runnable .batch (file_blobs , config )
5840
41+ ui_dir = str (ROOT / "ui" )
5942
60- @app .get ("/health" )
61- async def health () -> dict :
62- return {"status" : "ok" }
6343
44+ class StaticFilesSpa (StaticFiles ):
45+ async def get_response (
46+ self , path : str , scope : MutableMapping [str , Any ]
47+ ) -> Response :
48+ res = await super ().get_response (path , scope )
49+ if isinstance (res , FileResponse ) and res .status_code == 404 :
50+ res .status_code = 200
51+ return res
6452
65- ui_dir = str (ROOT / "ui" )
6653
6754if os .path .exists (ui_dir ):
68- app .mount ("" , StaticFiles (directory = ui_dir , html = True ), name = "ui" )
55+ app .mount ("" , StaticFilesSpa (directory = ui_dir , html = True ), name = "ui" )
6956else :
7057 logger .warn ("No UI directory found, serving API only." )
7158
0 commit comments