File size: 4,662 Bytes
a2df0c9
531990d
454d020
531990d
454d020
8f4cefb
531990d
 
 
 
d9bf42a
e73254b
3089d42
d9d895f
63971d2
531990d
 
 
d312f58
 
ed6fd56
b27b4c3
20d293c
bcd6d73
d9d895f
aaa82f0
ed6fd56
d9d895f
531990d
 
 
 
 
 
 
 
5066c0b
3ef184a
63971d2
 
 
3ef184a
531990d
 
 
 
5066c0b
531990d
ed6fd56
531990d
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
ed6fd56
 
 
 
531990d
 
 
ed6fd56
 
 
 
 
 
 
 
 
531990d
 
 
 
 
 
 
 
 
 
 
 
 
 
454d020
 
 
 
 
 
 
 
 
531990d
 
 
8f4cefb
 
d312f58
454d020
3089d42
e73254b
3089d42
ed6fd56
d312f58
 
454d020
9568173
454d020
ed6fd56
454d020
 
 
a2df0c9
 
 
ed6fd56
531990d
d312f58
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
import json
from fastapi import FastAPI
from fastapi.responses import RedirectResponse, JSONResponse
from fastapi.staticfiles import StaticFiles
from fastapi.middleware.cors import CORSMiddleware
from app.api import chat_api, conversation_api, management_api
from app.config.log import log_config
from loguru import logger
from environs import Env
from contextlib import asynccontextmanager
from app.db.factory import db_client
from gradio_chatbot import build_gradio_app, app_auth
import gradio as gr
import os
from app.core.initial_setup.setup import InitialSetup

print(log_config.get_log_level())

env = Env()
env.read_env()

DB_DATABASE_TYPE = env.str("DB_DATABASE_TYPE", "mongodb")

# special handling for Hugging Face Space
IS_HF_SPACE = os.environ.get("SPACE_ID") is not None
SPACE_URL = "https://lokumai-openai-openapi-template.hf.space" if IS_HF_SPACE else "http://localhost:7860"


@asynccontextmanager
async def lifespan(app: FastAPI):
    """
    Lifespan context manager for FastAPI application.
    Handles startup and shutdown events.
    """
    # Startup
    logger.info("Starting up application...")
    await db_client.connect()

    # Run initial setup if database type is embedded
    initial_setup = InitialSetup()
    await initial_setup.setup()

    yield

    # Shutdown
    logger.info("Shutting down application...")
    await db_client.close()


VERSION = "0.3.0"
TITLE = "Talk to your data chat and visualize API"
DESCRIPTION = """
Talk to your data chat and visualize API

    ## Chat
    You can use the chat API to talk to your data and visualize the results.

    ## Authentication
    All endpoints require API key authentication using the `Authorization` header.
    API keys are in the format: `sk-{username}-{base64_encoded_data}`
    
    ## Endpoints
    ### Chat (openai compatible APIs) - Given a list of messages comprising a conversation, the model will return a response.
    - GET  `/v1/chat/completions`: listChatCompletions - List stored chat completions. Only Chat completions that have been stored with the `store` parameter set to `true` will be returned.
    - POST `/v1/chat/completions`: createChatCompletion - Create a new chat completion.
    - GET  `/v1/chat/completions/{completion_id}`: getChatCompletion - Get a stored chat completion. Only Chat Completions that have been created with the `store` parameter set to `true` will be returned.
    - POST `/v1/chat/completions/{completion_id}`: modifyChatCompletion - Modify a stored chat completion.
    - DELETE `/v1/chat/completions/{completion_id}`: deleteChatCompletion - Delete a stored chat completion.
    - GET  `/v1/chat/completions/{completion_id}/messages`: getChatCompletionMessages - Get the messages in a stored chat completion.

    ### Plots( custom endpoints)
    - GET  `/v1/chat/completions/{completion_id}/messages/{message_id}/plots`: getChatPlotByMessage - Get the plot for a specific message in a chat.
  
"""

openapi_tags = [
    {
        "name": "chat",
        "description": "Chat API : Given a list of messages comprising a conversation, the model will return a response.",
    }
]

app = FastAPI(
    title=TITLE,
    description=DESCRIPTION,
    version=VERSION,
    docs_url="/docs",
    redoc_url="/redoc",
    openapi_url="/openapi.json",
    lifespan=lifespan,
    openapi_tags=openapi_tags,
    debug=True,
)

# Configure OpenAPI security scheme
app.openapi_components = {
    "securitySchemes": {
        "ApiKeyAuth": {
            "type": "apiKey",
            "in": "header",
            "name": "Authorization",
            "description": "API key in the format: sk-{username}-{base64_encoded_data}",
        }
    }
}

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

app.mount("/static", StaticFiles(directory="static"), name="static")
app.mount("/.well-known", StaticFiles(directory=".well-known"), name="well-known")
app.include_router(chat_api.router)
app.include_router(management_api.router)
app.include_router(conversation_api.router)

# Build and mount Gradio app
demo = build_gradio_app()
app = gr.mount_gradio_app(app, demo, path="/ui", auth=app_auth)


@app.get("/")
async def root():
    """Redirect root to Gradio UI"""
    return RedirectResponse(url="/ui")


@app.get("/manifest.json")
async def get_manifest():
    """Return the web app manifest"""
    manifest_path = os.path.join(os.path.dirname(__file__), "static", "manifest.json")
    with open(manifest_path, "r") as f:
        return JSONResponse(json.load(f))


# uv run uvicorn main:app --host 0.0.0.0 --port 7860 --reload