-
Notifications
You must be signed in to change notification settings - Fork 1
Expand file tree
/
Copy pathcc_webapp.py
More file actions
96 lines (75 loc) · 3.32 KB
/
cc_webapp.py
File metadata and controls
96 lines (75 loc) · 3.32 KB
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
import uvicorn
import toml
import logging
from types import MappingProxyType
from fastapi import FastAPI, Request, HTTPException
from fastapi.responses import HTMLResponse, JSONResponse
from fastapi.templating import Jinja2Templates
from pydantic import BaseModel
from cc_rag import get_rag_response
# Load TOML config and return an immutable MappingProxyType
with open("config.toml", "r", encoding="utf-8") as file:
CONFIG = MappingProxyType(toml.load(file))
# Configure logging
logging.basicConfig(level=logging.INFO)
logger = logging.getLogger(__name__)
# Create FastAPI app
app = FastAPI()
# Set up templates directory
templates = Jinja2Templates(directory="templates")
class QueryRequest(BaseModel):
query: str
model: str
# Display Home page
@app.get("/", response_class=HTMLResponse)
async def serve_home(request: Request):
"""Renders the HTML template for the user interface with dynamic model options."""
models = [
{"display_name": model_data["display_name"], "deployment_name": model_data["deployment_name"]}
for model_data in CONFIG["azure-ai"]["model"].values()
]
return templates.TemplateResponse("index.html", {"request": request, "models": models})
# Process Query
@app.post("/ask")
async def ask_question(request: QueryRequest):
query = request.query
model = request.model
if not query.strip():
raise HTTPException(status_code=422, detail="Query cannot be empty.")
logger.info(f"Received query: {query} | Model: {model}")
try:
response, prompt_tokens, completion_tokens = get_rag_response(query, model)
# Handle case where response is an error message
if isinstance(response, str) and "error" in response.lower():
raise HTTPException(status_code=500, detail=response)
# Validate token values
prompt_tokens = max(prompt_tokens, 1) # Prevent division by zero
completion_tokens = max(completion_tokens, 1)
data_source = CONFIG["confluence"]["wiki_url"]
model_data = CONFIG["azure-ai"]["model"].get(model, None)
if model_data:
input_cost = model_data["input_token_cost"]
output_cost = model_data["output_token_cost"]
token_cost_batch = model_data["token_cost_batch"]
else:
print(f"Model '{model}' not found in TOML configuration.")
input_tokens_cost = f"{(( prompt_tokens / token_cost_batch) * input_cost):.4f}"
output_tokens_cost = f"{(( completion_tokens / token_cost_batch) * output_cost):.4f}"
return JSONResponse({
"answer": response,
"input_tokens": prompt_tokens,
"output_tokens": completion_tokens,
"input_tokens_cost": input_tokens_cost,
"output_tokens_cost": output_tokens_cost,
"data_source": data_source
})
except HTTPException as http_error:
raise http_error # Return proper HTTP errors
except Exception as e:
logger.error(f"Unexpected error: {e}")
raise HTTPException(status_code=500, detail="An unexpected error occurred. Please try again later.")
if __name__ == "__main__":
try:
uvicorn.run("cc_webapp:app", host="0.0.0.0", port=8000, reload=True)
except Exception as e:
logger.error(f"Unexpected error occurred. Please try again later.: {e}")