main.py 3.5 KB
Newer Older
Timothy J. Baek's avatar
Timothy J. Baek committed
1
2
3
from bs4 import BeautifulSoup
import json
import markdown
4
import time
Timothy J. Baek's avatar
Timothy J. Baek committed
5
6
import os
import sys
Timothy J. Baek's avatar
Timothy J. Baek committed
7

Timothy J. Baek's avatar
Timothy J. Baek committed
8
from fastapi import FastAPI, Request, Depends
Timothy J. Baek's avatar
Timothy J. Baek committed
9
10
from fastapi.staticfiles import StaticFiles
from fastapi import HTTPException
Timothy J. Baek's avatar
Timothy J. Baek committed
11
from fastapi.responses import JSONResponse
Timothy J. Baek's avatar
Timothy J. Baek committed
12
13
from fastapi.middleware.wsgi import WSGIMiddleware
from fastapi.middleware.cors import CORSMiddleware
14
from starlette.exceptions import HTTPException as StarletteHTTPException
Timothy J. Baek's avatar
Timothy J. Baek committed
15

Timothy J. Baek's avatar
Timothy J. Baek committed
16

Timothy J. Baek's avatar
Timothy J. Baek committed
17
from litellm.proxy.proxy_server import ProxyConfig, initialize
Timothy J. Baek's avatar
Timothy J. Baek committed
18
19
from litellm.proxy.proxy_server import app as litellm_app

Timothy J. Baek's avatar
Timothy J. Baek committed
20
from apps.ollama.main import app as ollama_app
21
from apps.openai.main import app as openai_app
Timothy J. Baek's avatar
Timothy J. Baek committed
22
from apps.audio.main import app as audio_app
Timothy J. Baek's avatar
Timothy J. Baek committed
23
24
from apps.images.main import app as images_app
from apps.rag.main import app as rag_app
25
from apps.web.main import app as webui_app
Timothy J. Baek's avatar
Timothy J. Baek committed
26

Timothy J. Baek's avatar
Timothy J. Baek committed
27

28
from config import WEBUI_NAME, ENV, VERSION, CHANGELOG, FRONTEND_BUILD_DIR
Timothy J. Baek's avatar
Timothy J. Baek committed
29
from utils.utils import get_http_authorization_cred, get_current_user
Timothy J. Baek's avatar
Timothy J. Baek committed
30
31
32
33
34
35
36
37
38
39
40
41
42


class SPAStaticFiles(StaticFiles):
    async def get_response(self, path: str, scope):
        try:
            return await super().get_response(path, scope)
        except (HTTPException, StarletteHTTPException) as ex:
            if ex.status_code == 404:
                return await super().get_response("index.html", scope)
            else:
                raise ex


Timothy J. Baek's avatar
Timothy J. Baek committed
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
proxy_config = ProxyConfig()


async def config():
    router, model_list, general_settings = await proxy_config.load_config(
        router=None, config_file_path="./data/litellm/config.yaml"
    )

    await initialize(config="./data/litellm/config.yaml", telemetry=False)


async def startup():
    await config()


58
app = FastAPI(docs_url="/docs" if ENV == "dev" else None, redoc_url=None)
Timothy J. Baek's avatar
Timothy J. Baek committed
59
60
61
62
63
64
65
66
67
68
69
70

origins = ["*"]

app.add_middleware(
    CORSMiddleware,
    allow_origins=origins,
    allow_credentials=True,
    allow_methods=["*"],
    allow_headers=["*"],
)


Timothy J. Baek's avatar
Timothy J. Baek committed
71
72
73
74
75
@app.on_event("startup")
async def on_startup():
    await startup()


Timothy J. Baek's avatar
Timothy J. Baek committed
76
77
78
79
80
81
82
83
84
85
@app.middleware("http")
async def check_url(request: Request, call_next):
    start_time = int(time.time())
    response = await call_next(request)
    process_time = int(time.time()) - start_time
    response.headers["X-Process-Time"] = str(process_time)

    return response


Timothy J. Baek's avatar
Timothy J. Baek committed
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
@litellm_app.middleware("http")
async def auth_middleware(request: Request, call_next):
    auth_header = request.headers.get("Authorization", "")

    if ENV != "dev":
        try:
            user = get_current_user(get_http_authorization_cred(auth_header))
            print(user)
        except Exception as e:
            return JSONResponse(status_code=400, content={"detail": str(e)})

    response = await call_next(request)
    return response


101
app.mount("/api/v1", webui_app)
Timothy J. Baek's avatar
Timothy J. Baek committed
102
103
app.mount("/litellm/api", litellm_app)

104
app.mount("/ollama/api", ollama_app)
105
app.mount("/openai/api", openai_app)
Timothy J. Baek's avatar
Timothy J. Baek committed
106

Timothy J. Baek's avatar
Timothy J. Baek committed
107
app.mount("/images/api/v1", images_app)
Timothy J. Baek's avatar
Timothy J. Baek committed
108
app.mount("/audio/api/v1", audio_app)
Timothy J. Baek's avatar
Timothy J. Baek committed
109
110
app.mount("/rag/api/v1", rag_app)

111

Timothy J. Baek's avatar
Timothy J. Baek committed
112
113
@app.get("/api/config")
async def get_app_config():
Timothy J. Baek's avatar
Timothy J. Baek committed
114

Timothy J. Baek's avatar
Timothy J. Baek committed
115
116
    return {
        "status": True,
117
        "name": WEBUI_NAME,
Timothy J. Baek's avatar
Timothy J. Baek committed
118
        "version": VERSION,
Timothy J. Baek's avatar
Timothy J. Baek committed
119
120
121
122
123
124
        "images": images_app.state.ENABLED,
        "default_models": webui_app.state.DEFAULT_MODELS,
        "default_prompt_suggestions": webui_app.state.DEFAULT_PROMPT_SUGGESTIONS,
    }


Timothy J. Baek's avatar
Timothy J. Baek committed
125
126
@app.get("/api/changelog")
async def get_app_changelog():
Timothy J. Baek's avatar
Timothy J. Baek committed
127
    return CHANGELOG
Timothy J. Baek's avatar
Timothy J. Baek committed
128
129


130
131
132
app.mount("/static", StaticFiles(directory="static"), name="static")


133
134
app.mount(
    "/",
lucasew's avatar
lucasew committed
135
    SPAStaticFiles(directory=FRONTEND_BUILD_DIR, html=True),
136
137
    name="spa-static-files",
)