1
1
import logging
2
2
import os
3
3
from pathlib import Path
4
+ from typing import Any , MutableMapping
4
5
5
- from fastapi .exception_handlers import http_exception_handler
6
6
import 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
9
9
from fastapi .exceptions import HTTPException
10
+ from fastapi .responses import FileResponse
10
11
from fastapi .staticfiles import StaticFiles
12
+ from starlette .responses import Response
11
13
12
- import app .storage as storage
13
14
from app .api import router as api_router
14
- from app .auth .handlers import AuthedUser
15
15
from app .lifespan import lifespan
16
- from app .upload import convert_ingestion_input_to_blob , ingest_runnable
17
16
18
17
logger = logging .getLogger (__name__ )
19
18
@@ -31,41 +30,29 @@ async def httpx_http_status_error_handler(request, exc: httpx.HTTPStatusError):
31
30
ROOT = Path (__file__ ).parent .parent
32
31
33
32
34
- app .include_router (api_router )
35
-
33
+ @app .get ("/ok" )
34
+ async def ok ():
35
+ return {"ok" : True }
36
36
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 )
43
37
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" )
49
39
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 )
58
40
41
+ ui_dir = str (ROOT / "ui" )
59
42
60
- @app .get ("/health" )
61
- async def health () -> dict :
62
- return {"status" : "ok" }
63
43
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
64
52
65
- ui_dir = str (ROOT / "ui" )
66
53
67
54
if 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" )
69
56
else :
70
57
logger .warn ("No UI directory found, serving API only." )
71
58
0 commit comments