Skip to content

Commit b957892

Browse files
Route refactoring, HTMX
1 parent a5751b2 commit b957892

File tree

5 files changed

+78
-32
lines changed

5 files changed

+78
-32
lines changed

main.py

Lines changed: 22 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -57,28 +57,42 @@ async def read_home(request: Request):
5757

5858
@app.get("/basic-chat")
5959
async def read_basic_chat(request: Request, messages: list = [], thread_id: str = None):
60+
# Get assistant ID from environment variables
61+
load_dotenv()
62+
assistant_id = os.getenv("ASSISTANT_ID")
63+
6064
return templates.TemplateResponse(
6165
"examples/basic-chat.html",
6266
{
6367
"request": request,
68+
"assistant_id": assistant_id, # Add assistant_id to template context
6469
"messages": messages,
6570
"thread_id": thread_id
6671
}
6772
)
6873

6974
@app.get("/file-search")
7075
async def read_file_search(request: Request, messages: list = [], thread_id: str = None):
76+
# Get assistant ID from environment variables
77+
load_dotenv()
78+
assistant_id = os.getenv("ASSISTANT_ID")
79+
7180
return templates.TemplateResponse(
7281
"examples/file-search.html",
7382
{
7483
"request": request,
7584
"messages": messages,
7685
"thread_id": thread_id,
86+
"assistant_id": assistant_id, # Add assistant_id to template context
7787
}
7888
)
7989

8090
@app.get("/function-calling")
8191
async def read_function_calling(request: Request, messages: list = [], thread_id: str = None):
92+
# Get assistant ID from environment variables
93+
load_dotenv()
94+
assistant_id = os.getenv("ASSISTANT_ID")
95+
8296
# Define the condition class map
8397
conditionClassMap = {
8498
"Cloudy": "weatherBGCloudy",
@@ -97,16 +111,23 @@ async def read_function_calling(request: Request, messages: list = [], thread_id
97111
"conditions": "Sunny",
98112
"isEmpty": True,
99113
"thread_id": thread_id,
100-
"messages": messages
114+
"messages": messages,
115+
"assistant_id": assistant_id, # Add assistant_id to template context
101116
}
102117
)
103118

119+
104120
@app.get("/all")
105121
async def read_all(request: Request, messages: list = [], thread_id: str = None):
122+
# Get assistant ID from environment variables
123+
load_dotenv()
124+
assistant_id = os.getenv("ASSISTANT_ID")
125+
106126
return templates.TemplateResponse(
107127
"examples/all.html",
108128
{
109129
"request": request,
130+
"assistant_id": assistant_id, # Add assistant_id to template context
110131
"thread_id": thread_id,
111132
"messages": messages
112133
}

routers/files.py

Lines changed: 27 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,10 @@
1212
load_dotenv()
1313
assistant_id: str = os.getenv("ASSISTANT_ID")
1414

15-
router: APIRouter = APIRouter(prefix="/assistants/{assistant_id}/files", tags=["assistants_files"])
15+
router: APIRouter = APIRouter(
16+
prefix="/assistants/{assistant_id}/files",
17+
tags=["assistants_files"]
18+
)
1619

1720
# Pydantic model for DELETE request body
1821
class DeleteRequest(BaseModel):
@@ -40,12 +43,10 @@ async def get_or_create_vector_store(assistantId: str, client: AsyncOpenAI = Dep
4043

4144

4245
@router.get("/files/{file_id}")
43-
async def get_file(file_id: str, client: AsyncOpenAI = Depends(lambda: AsyncOpenAI())):
44-
"""
45-
Endpoint to download a file by file ID.
46-
"""
46+
async def get_file(file_id: str):
4747
try:
4848
# Retrieve file metadata and content concurrently
49+
client = AsyncOpenAI()
4950
file, file_content = await client.files.retrieve(file_id), await client.files.content(file_id)
5051

5152
# Return the file content as a streaming response
@@ -59,19 +60,28 @@ async def get_file(file_id: str, client: AsyncOpenAI = Depends(lambda: AsyncOpen
5960

6061

6162
@router.post("/upload")
62-
async def upload_file(file: UploadFile = File(...), client: AsyncOpenAI = Depends(lambda: AsyncOpenAI())):
63-
# Process file and upload to OpenAI
64-
vector_store_id = await get_or_create_vector_store(assistant_id, client)
65-
openai_file = await client.files.create(
66-
file=file.file,
67-
purpose="assistants"
68-
)
69-
await client.beta.vectorStores.files.create(vector_store_id, {
70-
"file_id": openai_file.id
71-
})
72-
return {"message": "File uploaded successfully"}
63+
async def upload_file(file: UploadFile = File(...)):
64+
try:
65+
client = AsyncOpenAI()
66+
67+
# Handles multiple files through the form
68+
# Process file and upload to OpenAI
69+
vector_store_id = await get_or_create_vector_store(assistant_id)
70+
71+
openai_file = await client.files.create(
72+
file=file.file,
73+
purpose="assistants"
74+
)
75+
await client.beta.vectorStores.files.create(vector_store_id, {
76+
"file_id": openai_file.id
77+
})
78+
return {"message": "File uploaded successfully"}
79+
except Exception as e:
80+
# Handle exceptions and return an HTTP error response
81+
raise HTTPException(status_code=500, detail=str(e))
82+
7383

74-
@router.get("/files")
84+
@router.get("")
7585
async def list_files(client: AsyncOpenAI = Depends(lambda: AsyncOpenAI())):
7686
# List files in the vector store
7787
vector_store_id = await get_or_create_vector_store(assistant_id, client)

routers/messages.py

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -9,9 +9,14 @@
99
from utils.threads import create_thread
1010

1111
logger: logging.Logger = logging.getLogger("uvicorn.error")
12+
logger.setLevel(logging.DEBUG)
1213

1314
# Initialize the router
14-
router: APIRouter = APIRouter()
15+
router: APIRouter = APIRouter(
16+
prefix="/assistants/{assistant_id}/messages",
17+
tags=["assistants_messages"]
18+
)
19+
1520

1621
# Send a new message to a thread
1722
@router.post("/send_message")

templates/components/file-viewer.html

Lines changed: 21 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
<div class="fileViewer">
2-
<div class="filesList {{ 'grow' if files|length != 0 else '' }}">
2+
<div class="filesList {{ 'grow' if files|length != 0 else '' }}"
3+
hx-get="/assistants/{{ assistant_id }}/files"
4+
hx-trigger="every 2s">
35
{% if files|length == 0 %}
46
<div class="title">Attach files to test file search</div>
57
{% else %}
@@ -10,25 +12,31 @@
1012
<span class="fileStatus">{{ file.status }}</span>
1113
</div>
1214
<span>
13-
<form method="POST" action="/delete-file">
14-
<input type="hidden" name="file_id" value="{{ file.file_id }}">
15-
<button type="submit" class="fileDeleteIcon">
16-
<!-- TrashIcon component -->
17-
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" height="12" width="12" fill="#353740">
18-
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.15736 1.33332C4.8911 1.33332 4.65864 1.51361 4.59238 1.77149L4.4214 2.43693H7.58373L7.41275 1.77149C7.34649 1.51361 7.11402 1.33332 6.84777 1.33332H5.15736ZM8.78829 2.43693L8.54271 1.48115C8.34393 0.707516 7.64653 0.166656 6.84777 0.166656H5.15736C4.35859 0.166656 3.6612 0.707515 3.46241 1.48115L3.21683 2.43693H1.33333C1.01117 2.43693 0.75 2.6981 0.75 3.02026C0.75 3.34243 1.01117 3.6036 1.33333 3.6036H1.39207L2.10068 10.2683C2.19529 11.1582 2.94599 11.8333 3.84087 11.8333H8.15913C9.05401 11.8333 9.80471 11.1582 9.89932 10.2683L10.6079 3.6036H10.6667C10.9888 3.6036 11.25 3.34243 11.25 3.02026C11.25 2.6981 10.9888 2.43693 10.6667 2.43693H8.78829ZM9.43469 3.6036H2.56531L3.2608 10.145C3.29234 10.4416 3.54257 10.6667 3.84087 10.6667H8.15913C8.45743 10.6667 8.70766 10.4416 8.7392 10.145L9.43469 3.6036ZM4.83333 4.83332C5.1555 4.83332 5.41667 5.09449 5.41667 5.41666V8.33332C5.41667 8.65549 5.1555 8.91666 4.83333 8.91666C4.51117 8.91666 4.25 8.65549 4.25 8.33332V5.41666C4.25 5.09449 4.51117 4.83332 4.83333 4.83332ZM7.16667 4.83332C7.48883 4.83332 7.75 5.09449 7.75 5.41666V8.33332C7.75 8.65549 7.48883 8.91666 7.16667 8.91666C6.8445 8.91666 6.58333 8.65549 6.58333 8.33332V5.41666C6.58333 5.09449 6.8445 4.83332 7.16667 4.83332Z"/>
19-
</svg>
20-
</button>
21-
</form>
15+
<button hx-delete="/assistants/{{ assistant_id }}/files/delete"
16+
hx-vals='{"file_id": "{{ file.file_id }}"}'
17+
hx-target=".filesList"
18+
class="fileDeleteIcon">
19+
<!-- TrashIcon component -->
20+
<svg xmlns="http://www.w3.org/2000/svg" viewBox="0 0 12 12" height="12" width="12" fill="#353740">
21+
<path fill-rule="evenodd" clip-rule="evenodd" d="M5.15736 1.33332C4.8911 1.33332 4.65864 1.51361 4.59238 1.77149L4.4214 2.43693H7.58373L7.41275 1.77149C7.34649 1.51361 7.11402 1.33332 6.84777 1.33332H5.15736ZM8.78829 2.43693L8.54271 1.48115C8.34393 0.707516 7.64653 0.166656 6.84777 0.166656H5.15736C4.35859 0.166656 3.6612 0.707515 3.46241 1.48115L3.21683 2.43693H1.33333C1.01117 2.43693 0.75 2.6981 0.75 3.02026C0.75 3.34243 1.01117 3.6036 1.33333 3.6036H1.39207L2.10068 10.2683C2.19529 11.1582 2.94599 11.8333 3.84087 11.8333H8.15913C9.05401 11.8333 9.80471 11.1582 9.89932 10.2683L10.6079 3.6036H10.6667C10.9888 3.6036 11.25 3.34243 11.25 3.02026C11.25 2.6981 10.9888 2.43693 10.6667 2.43693H8.78829ZM9.43469 3.6036H2.56531L3.2608 10.145C3.29234 10.4416 3.54257 10.6667 3.84087 10.6667H8.15913C8.45743 10.6667 8.70766 10.4416 8.7392 10.145L9.43469 3.6036ZM4.83333 4.83332C5.1555 4.83332 5.41667 5.09449 5.41667 5.41666V8.33332C5.41667 8.65549 5.1555 8.91666 4.83333 8.91666C4.51117 8.91666 4.25 8.65549 4.25 8.33332V5.41666C4.25 5.09449 4.51117 4.83332 4.83333 4.83332ZM7.16667 4.83332C7.48883 4.83332 7.75 5.09449 7.75 5.41666V8.33332C7.75 8.65549 7.48883 8.91666 7.16667 8.91666C6.8445 8.91666 6.58333 8.65549 6.58333 8.33332V5.41666C6.58333 5.09449 6.8445 4.83332 7.16667 4.83332Z"/>
22+
</svg>
23+
</button>
2224
</span>
2325
</div>
2426
{% endfor %}
2527
{% endif %}
2628
</div>
2729
<div class="fileUploadContainer">
28-
<form method="POST" action="/upload-file" enctype="multipart/form-data">
30+
<form hx-post="/assistants/{{ assistant_id }}/files/upload"
31+
hx-encoding="multipart/form-data"
32+
hx-target=".filesList">
2933
<label for="file-upload" class="fileUploadBtn">Attach files</label>
30-
<input type="file" id="file-upload" name="file-upload" class="fileUploadInput" multiple>
31-
<button type="submit">Upload</button>
34+
<input type="file"
35+
id="file-upload"
36+
name="file-upload"
37+
class="fileUploadInput"
38+
multiple
39+
hx-trigger="change">
3240
</form>
3341
</div>
3442
</div>

templates/layout.html

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,8 @@
77
<link rel="icon" href="{{ url_for('static', path='openai.svg') }}">
88
<link rel="stylesheet" href="{{ url_for('static', path='styles.css') }}">
99
<link rel="favicon" href="{{ url_for('static', path='favicon.png') }}">
10+
<script src="https://unpkg.com/[email protected]"></script>
11+
<script src="https://unpkg.com/htmx.org/dist/ext/sse.js"></script>
1012
</head>
1113
<body>
1214
{% block content %}

0 commit comments

Comments
 (0)