Skip to content

Commit 9662f13

Browse files
Merge pull request #8 from Promptly-Technologies-LLC/5-test-and-hook-up-warnings-component
Create setup page for setting the API key and creating an assistant
2 parents 365a22d + 5c68943 commit 9662f13

File tree

13 files changed

+335
-173
lines changed

13 files changed

+335
-173
lines changed

.env.example

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,2 +1,2 @@
1-
OPENAI_API_KEY=
1+
OPENAI_API_KEY=
22
ASSISTANT_ID=

README.md

Lines changed: 6 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -13,29 +13,21 @@ git clone https://github.com/Promptly-Technologies-LLC/openai-assistants-python-
1313
cd openai-assistants-python-quickstart
1414
```
1515

16-
### 2. Set your [OpenAI API key](https://platform.openai.com/api-keys)
17-
18-
```shell
19-
cp .env.example .env
20-
```
21-
22-
### 3. Install dependencies
16+
### 2. Install dependencies
2317

2418
```shell
2519
uv venv
2620
uv pip install -r pyproject.toml
2721
```
2822

29-
### 4. Create an assistant
23+
### 3. Run the FastAPI server
3024

3125
```shell
32-
uv run create_assistant.py
26+
uv run uvicorn main:app --host 0.0.0.0 --port 8000 --reload
3327
```
3428

35-
### 5. Run the FastAPI server
29+
### 4. Navigate to [http://localhost:8000](http://localhost:8000).
3630

37-
```shell
38-
uv run uvicorn main:app --host 0.0.0.0 --port 8000 --reload
39-
```
31+
### 5. Set your OpenAI API key and create an assistant in the GUI
4032

41-
### 6. Navigate to [http://localhost:8000](http://localhost:8000).
33+
If your OPENAI_API_KEY or ASSISTANT_ID are not set, you will be redirected to the setup page where you can set them. (The values will be saved in a .env file in the root of the project.) Once set, you will be redirected to the home page and can begin a chat session.

__pycache__/main.cpython-312.pyc

-3.89 KB
Binary file not shown.

main.py

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -1,17 +1,16 @@
11
import os
22
import logging
3-
import dotenv
3+
from dotenv import load_dotenv
44
from contextlib import asynccontextmanager
55
from fastapi import FastAPI, Request
66
from fastapi.staticfiles import StaticFiles
77
from fastapi.templating import Jinja2Templates
8-
from routers import messages, assistants_files, tool_outputs
8+
from fastapi.responses import RedirectResponse
9+
from routers import files, messages, tools, api_keys, assistants
910

1011

1112
logger = logging.getLogger("uvicorn.error")
1213

13-
dotenv.load_dotenv()
14-
1514
@asynccontextmanager
1615
async def lifespan(app: FastAPI):
1716
# Optional startup logic
@@ -22,9 +21,10 @@ async def lifespan(app: FastAPI):
2221

2322
# Mount routers
2423
app.include_router(messages.router)
25-
app.include_router(assistants_files.router)
26-
app.include_router(tool_outputs.router)
27-
24+
app.include_router(files.router)
25+
app.include_router(tools.router)
26+
app.include_router(api_keys.router)
27+
app.include_router(assistants.router)
2828

2929
# Mount static files (e.g., CSS, JS)
3030
app.mount("/static", StaticFiles(directory=os.path.join(os.getcwd(), "static")), name="static")
@@ -36,6 +36,11 @@ async def lifespan(app: FastAPI):
3636
async def read_home(request: Request):
3737
logger.info("Home page requested")
3838

39+
# Check if environment variables are missing
40+
load_dotenv(override=True)
41+
if not os.getenv("OPENAI_API_KEY") or not os.getenv("ASSISTANT_ID"):
42+
return RedirectResponse(url="/setup")
43+
3944
categories = {
4045
"Basic chat": "basic-chat",
4146
"File search": "file-search",
@@ -107,6 +112,23 @@ async def read_all(request: Request, messages: list = [], thread_id: str = None)
107112
}
108113
)
109114

115+
# Add new setup route
116+
@app.get("/setup")
117+
async def read_setup(request: Request, message: str = None):
118+
# Check if assistant ID is missing
119+
load_dotenv(override=True)
120+
if not os.getenv("OPENAI_API_KEY"):
121+
message="OpenAI API key is missing."
122+
elif not os.getenv("ASSISTANT_ID"):
123+
message="Assistant ID is missing."
124+
else:
125+
message="All set up!"
126+
127+
return templates.TemplateResponse(
128+
"setup.html",
129+
{"request": request, "message": message}
130+
)
131+
110132
if __name__ == "__main__":
111133
import uvicorn
112134

routers/api_keys.py

Lines changed: 32 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
import logging
2+
from fastapi import APIRouter, HTTPException, Form
3+
from fastapi.responses import RedirectResponse
4+
from utils.create_assistant import update_env_file
5+
6+
# Configure logger
7+
logger: logging.Logger = logging.getLogger("uvicorn.error")
8+
9+
router = APIRouter(prefix="/api-keys", tags=["API Keys"])
10+
11+
@router.post("/set")
12+
async def set_openai_api_key(api_key: str = Form()):
13+
"""
14+
Set the OpenAI API key in the application's environment variables.
15+
16+
Args:
17+
api_key: OpenAI API key received from form submission
18+
19+
Returns:
20+
RedirectResponse: Redirects to home page on success
21+
22+
Raises:
23+
HTTPException: If there's an error updating the environment file
24+
"""
25+
try:
26+
update_env_file("OPENAI_API_KEY", api_key, logger)
27+
return RedirectResponse(url="/", status_code=303)
28+
except Exception as e:
29+
raise HTTPException(
30+
status_code=500,
31+
detail=f"Failed to update API key: {str(e)}"
32+
)

routers/assistants.py

Lines changed: 38 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,38 @@
1+
from fastapi import APIRouter, Depends
2+
from fastapi.responses import RedirectResponse
3+
from openai import AsyncOpenAI
4+
from utils.create_assistant import create_or_update_assistant, request
5+
import logging
6+
import os
7+
from dotenv import load_dotenv
8+
9+
# Configure logger
10+
logger = logging.getLogger("uvicorn.error")
11+
12+
# Load environment variables
13+
load_dotenv()
14+
15+
router = APIRouter(
16+
prefix="/assistants",
17+
tags=["assistants"]
18+
)
19+
20+
21+
@router.post("/create-update")
22+
async def create_update_assistant(
23+
client: AsyncOpenAI = Depends(lambda: AsyncOpenAI())
24+
):
25+
"""
26+
Create a new assistant or update an existing one.
27+
Returns the assistant ID and status of the operation.
28+
"""
29+
assistant_id = os.getenv("ASSISTANT_ID")
30+
31+
assistant_id: str = await create_or_update_assistant(
32+
client=client,
33+
assistant_id=assistant_id,
34+
request=request,
35+
logger=logger
36+
)
37+
38+
return RedirectResponse(url="/", status_code=303)
File renamed without changes.
File renamed without changes.

static/styles.css

Lines changed: 39 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -452,3 +452,42 @@ pre {
452452
color: #b8b8b8;
453453
margin-right: 8px;
454454
}
455+
456+
.setupContainer {
457+
display: flex;
458+
flex-direction: column;
459+
align-items: center;
460+
gap: 24px;
461+
max-width: 600px;
462+
width: 100%;
463+
padding: 40px 20px;
464+
}
465+
466+
.setupForm {
467+
display: flex;
468+
flex-direction: column;
469+
align-items: center;
470+
gap: 20px;
471+
width: 100%;
472+
}
473+
474+
.inputWrapper {
475+
margin-bottom: 20px;
476+
width: 100%;
477+
max-width: 400px;
478+
display: flex;
479+
justify-content: center;
480+
}
481+
482+
.setupForm form {
483+
display: flex;
484+
flex-direction: column;
485+
align-items: center;
486+
width: 100%;
487+
}
488+
489+
.setupMessage {
490+
font-size: 1.1em;
491+
text-align: center;
492+
margin-bottom: 8px;
493+
}

templates/components/warnings.html

Lines changed: 0 additions & 22 deletions
This file was deleted.

0 commit comments

Comments
 (0)