Spaces:
Runtime error
Runtime error
Zwea Htet
commited on
Commit
Β·
ae5391f
1
Parent(s):
6288a82
fixed bugs
Browse files- index.json +0 -0
- main.py +115 -9
- requirements.txt +2 -1
- static/icons/icons8-mind-map.gif +0 -0
- static/{script.js β scripts/chatbot.js} +33 -6
- static/scripts/login.js +39 -0
- static/styles/{chat.css β chatbot.css} +0 -0
- static/styles/login.css +31 -0
- templates/base.html +4 -2
- templates/{chat.html β chatbot.html} +4 -5
- templates/login.html +9 -7
index.json
CHANGED
The diff for this file is too large to render.
See raw diff
|
|
main.py
CHANGED
@@ -2,11 +2,14 @@ import datetime
|
|
2 |
import os
|
3 |
|
4 |
import openai
|
|
|
5 |
import uvicorn
|
6 |
from dotenv import load_dotenv
|
7 |
# from flask import Flask, redirect, render_template, request, session, url_for
|
8 |
-
from fastapi import FastAPI, Form, Request
|
9 |
-
|
|
|
|
|
10 |
from fastapi.staticfiles import StaticFiles
|
11 |
from fastapi.templating import Jinja2Templates
|
12 |
|
@@ -15,7 +18,11 @@ from models.bloom import initialize_index
|
|
15 |
load_dotenv()
|
16 |
app = FastAPI()
|
17 |
app.secret_key = os.environ.get('SECRET_KEY', 'my-secret-key')
|
18 |
-
openai.api_key = os.environ.get("OPENAI_API_KEY")
|
|
|
|
|
|
|
|
|
19 |
|
20 |
# mounts the static folder that contains the css file
|
21 |
app.mount("/static", StaticFiles(directory="static", html=True), name="static")
|
@@ -24,18 +31,117 @@ app.mount("/static", StaticFiles(directory="static", html=True), name="static")
|
|
24 |
# with the dialog form the user and bot
|
25 |
templates = Jinja2Templates(directory="templates")
|
26 |
|
27 |
-
|
|
|
28 |
|
29 |
@app.get("/", response_class=HTMLResponse)
|
30 |
async def home(request: Request):
|
31 |
-
return templates.TemplateResponse('
|
32 |
|
33 |
-
|
34 |
-
|
35 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
36 |
bot_reply = index.query(input)
|
37 |
return {"bot_reply": bot_reply}
|
38 |
|
39 |
if __name__ == "__main__":
|
40 |
-
# index = initialize_index("index.json")
|
41 |
uvicorn.run("main:app", reload=True)
|
|
|
2 |
import os
|
3 |
|
4 |
import openai
|
5 |
+
import requests
|
6 |
import uvicorn
|
7 |
from dotenv import load_dotenv
|
8 |
# from flask import Flask, redirect, render_template, request, session, url_for
|
9 |
+
from fastapi import (Cookie, Depends, FastAPI, Form, HTTPException, Request,
|
10 |
+
Response)
|
11 |
+
from fastapi.responses import HTMLResponse, RedirectResponse
|
12 |
+
from fastapi.security import APIKeyHeader
|
13 |
from fastapi.staticfiles import StaticFiles
|
14 |
from fastapi.templating import Jinja2Templates
|
15 |
|
|
|
18 |
load_dotenv()
|
19 |
app = FastAPI()
|
20 |
app.secret_key = os.environ.get('SECRET_KEY', 'my-secret-key')
|
21 |
+
# openai.api_key = os.environ.get("OPENAI_API_KEY")
|
22 |
+
openai_api_key_header = APIKeyHeader(name="token")
|
23 |
+
index = None
|
24 |
+
# index = initialize_index("index.json")
|
25 |
+
OPENAI_API_KEY = ""
|
26 |
|
27 |
# mounts the static folder that contains the css file
|
28 |
app.mount("/static", StaticFiles(directory="static", html=True), name="static")
|
|
|
31 |
# with the dialog form the user and bot
|
32 |
templates = Jinja2Templates(directory="templates")
|
33 |
|
34 |
+
# user data
|
35 |
+
user = {}
|
36 |
|
37 |
@app.get("/", response_class=HTMLResponse)
|
38 |
async def home(request: Request):
|
39 |
+
return templates.TemplateResponse('login.html', {"request": request})
|
40 |
|
41 |
+
def validate(token: str):
|
42 |
+
api_endpoint = "https://api.openai.com/v1/chat/completions"
|
43 |
+
api_key = token
|
44 |
+
|
45 |
+
headers = {
|
46 |
+
"Content-Type" : "application/json",
|
47 |
+
"Authorization": f"Bearer {api_key}"
|
48 |
+
}
|
49 |
+
|
50 |
+
messages = [
|
51 |
+
{"role": "user", "content": "Say this is a test!"}
|
52 |
+
]
|
53 |
+
|
54 |
+
data = {
|
55 |
+
"model": "gpt-3.5-turbo",
|
56 |
+
"messages": messages
|
57 |
+
}
|
58 |
+
|
59 |
+
response = requests.post(api_endpoint, json=data, headers=headers)
|
60 |
+
return response
|
61 |
+
|
62 |
+
# Beware that most browsers cache GET requests
|
63 |
+
# (i.e., saved in browser's history), thus making
|
64 |
+
# them less secure compared to POST, as the data
|
65 |
+
# sent are part of the URL and visible to anyone
|
66 |
+
# who has access to the device. Thus, GET method
|
67 |
+
# should not be used when sending passwords or
|
68 |
+
# other sensitive information.
|
69 |
+
# @app.post("/login", response_class=HTMLResponse)
|
70 |
+
# async def login(token: str, request: Request):
|
71 |
+
# # form = await request.form()
|
72 |
+
# # print("login form data:", form.values())
|
73 |
+
# # api_key = form.get("access_token")
|
74 |
+
# print("apikey from login main.py: ", token)
|
75 |
+
# try:
|
76 |
+
# response = validate(token)
|
77 |
+
# print("login response: ", response.json())
|
78 |
+
# if ("error" in response.json()):
|
79 |
+
# error = response.json()["error"]
|
80 |
+
# raise HTTPException(status_code=400, detail=error["message"])
|
81 |
+
# except Exception as e:
|
82 |
+
# context = {"request": request, "error_message": str(e)}
|
83 |
+
# print("login error: ", context)
|
84 |
+
# return templates.TemplateResponse('login.html', context=context)
|
85 |
+
|
86 |
+
# return templates.TemplateResponse("chatbot.html", {"request": request})
|
87 |
+
|
88 |
+
# @app.post("/login")
|
89 |
+
# async def login(token: str, response: Response):
|
90 |
+
# print("apikey from login main.py: ", token)
|
91 |
+
|
92 |
+
# response = validate(token)
|
93 |
+
# print("login response: ", response.json())
|
94 |
+
# if ("error" in response.json()):
|
95 |
+
# error = response.json()["error"]
|
96 |
+
# # Redirect back to the login page with an error message
|
97 |
+
# response.set_cookie(key="message", value=error.message)
|
98 |
+
# return RedirectResponse(url="/login")
|
99 |
+
|
100 |
+
# # Store the session token or other identifying information in a cookie
|
101 |
+
|
102 |
+
# # response.set_cookie(key="username", value=username)
|
103 |
+
# # Redirect to the chatbot page upon successful login
|
104 |
+
# return RedirectResponse(url="/chatbot")
|
105 |
+
|
106 |
+
@app.post("/login")
|
107 |
+
async def login(token: str, response: Response):
|
108 |
+
result = validate(token)
|
109 |
+
print("login response: ", result.json())
|
110 |
+
if ("error" in result.json()):
|
111 |
+
error = result.json()["error"]
|
112 |
+
response.set_cookie(key="message", value=error["message"])
|
113 |
+
return {"error": error["message"]}
|
114 |
+
else:
|
115 |
+
return {"redirect": "/chatbot"}
|
116 |
+
|
117 |
+
@app.post("/initLlamaIndex")
|
118 |
+
async def initLlamaIndex(token: str):
|
119 |
+
openai.api_key = token
|
120 |
+
global index
|
121 |
+
index = initialize_index("index.json")
|
122 |
+
return {"success": True}
|
123 |
+
|
124 |
+
# Chatbot endpoint
|
125 |
+
@app.get("/chatbot", response_class=HTMLResponse)
|
126 |
+
async def chatbot(request: Request):
|
127 |
+
startTime = ""
|
128 |
+
context = {"request": request, "startTime": startTime}
|
129 |
+
return templates.TemplateResponse("chatbot.html", context=context)
|
130 |
+
|
131 |
+
|
132 |
+
# @app.get("/chatbot", response_class=HTMLResponse)
|
133 |
+
# async def chatbot(request: Request, username: str = Cookie(None)):
|
134 |
+
# if not username:
|
135 |
+
# # Redirect back to the login page if the user is not authenticated
|
136 |
+
# return RedirectResponse(url="/login")
|
137 |
+
# else:
|
138 |
+
# # Render the chatbot page with the username passed to the template
|
139 |
+
# return templates.TemplateResponse("chatbot.html", {"request": request, "username": username})
|
140 |
+
|
141 |
+
@app.get("/reply")
|
142 |
+
def reply(input: str):
|
143 |
bot_reply = index.query(input)
|
144 |
return {"bot_reply": bot_reply}
|
145 |
|
146 |
if __name__ == "__main__":
|
|
|
147 |
uvicorn.run("main:app", reload=True)
|
requirements.txt
CHANGED
@@ -14,4 +14,5 @@ panda
|
|
14 |
numpy
|
15 |
langchain
|
16 |
python-dotenv
|
17 |
-
python-multipart
|
|
|
|
14 |
numpy
|
15 |
langchain
|
16 |
python-dotenv
|
17 |
+
python-multipart
|
18 |
+
httpx
|
static/icons/icons8-mind-map.gif
ADDED
static/{script.js β scripts/chatbot.js}
RENAMED
@@ -1,6 +1,7 @@
|
|
1 |
const msgerForm = get(".msger-inputarea");
|
2 |
const msgerInput = get(".msger-input");
|
3 |
const msgerChat = get(".msger-chat");
|
|
|
4 |
|
5 |
// Icons made by Freepik from www.flaticon.com
|
6 |
const BOT_IMG = "../static/icons/dialogflow-insights-svgrepo-com.svg";
|
@@ -16,7 +17,9 @@ msgerForm.addEventListener("submit", async (event) => {
|
|
16 |
|
17 |
appendMessage(PERSON_NAME, PERSON_IMG, "right", msgText);
|
18 |
msgerInput.value = "";
|
|
|
19 |
botResponse(msgText);
|
|
|
20 |
});
|
21 |
|
22 |
function appendMessage(name, img, side, text) {
|
@@ -43,14 +46,38 @@ function appendMessage(name, img, side, text) {
|
|
43 |
|
44 |
async function botResponse(text) {
|
45 |
// Bot Response
|
46 |
-
|
47 |
-
|
48 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
49 |
|
50 |
-
|
|
|
|
|
|
|
51 |
|
52 |
-
|
53 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
54 |
|
55 |
// Utils
|
56 |
function get(selector, root = document) {
|
|
|
1 |
const msgerForm = get(".msger-inputarea");
|
2 |
const msgerInput = get(".msger-input");
|
3 |
const msgerChat = get(".msger-chat");
|
4 |
+
const isUserVerified = false;
|
5 |
|
6 |
// Icons made by Freepik from www.flaticon.com
|
7 |
const BOT_IMG = "../static/icons/dialogflow-insights-svgrepo-com.svg";
|
|
|
17 |
|
18 |
appendMessage(PERSON_NAME, PERSON_IMG, "right", msgText);
|
19 |
msgerInput.value = "";
|
20 |
+
|
21 |
botResponse(msgText);
|
22 |
+
// authenticate(msgText);
|
23 |
});
|
24 |
|
25 |
function appendMessage(name, img, side, text) {
|
|
|
46 |
|
47 |
async function botResponse(text) {
|
48 |
// Bot Response
|
49 |
+
try {
|
50 |
+
const response = await fetch(`reply?input=${text}`);
|
51 |
+
const data = await response.json();
|
52 |
+
const reply = data.bot_reply;
|
53 |
+
appendMessage(BOT_NAME, BOT_IMG, "left", reply.response);
|
54 |
+
} catch (error) {
|
55 |
+
console.error(error);
|
56 |
+
appendMessage(
|
57 |
+
BOT_NAME,
|
58 |
+
BOT_IMG,
|
59 |
+
"left",
|
60 |
+
"Sorry, I'm not able to respond at the moment."
|
61 |
+
);
|
62 |
+
}
|
63 |
+
}
|
64 |
|
65 |
+
// async function authenticate(token) {
|
66 |
+
// const response = await fetch(`login?token=${token}`, {
|
67 |
+
// method: "POST",
|
68 |
+
// });
|
69 |
|
70 |
+
// const data = await response.json();
|
71 |
+
// console.log("data", data);
|
72 |
+
|
73 |
+
// if ("error" in data) {
|
74 |
+
// error = response.json()["error"];
|
75 |
+
// appendMessage(BOT_NAME, BOT_IMG, "left", error["message"]);
|
76 |
+
// } else {
|
77 |
+
// isUserVerified = true;
|
78 |
+
// appendMessage(BOT_NAME, BOT_IMG, "left", "How can I can help you?");
|
79 |
+
// }
|
80 |
+
// }
|
81 |
|
82 |
// Utils
|
83 |
function get(selector, root = document) {
|
static/scripts/login.js
ADDED
@@ -0,0 +1,39 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
// show the loading animation when the login form is submitted
|
2 |
+
const loginBox = document.querySelector(".login-box");
|
3 |
+
const loginForm = document.querySelector(".login-form");
|
4 |
+
const tokenInput = document.getElementById("accessToken");
|
5 |
+
const loadingContainer = document.querySelector(".loading-container");
|
6 |
+
|
7 |
+
// some animations for validating token
|
8 |
+
// and initializing index
|
9 |
+
|
10 |
+
loginForm.addEventListener("submit", async (event) => {
|
11 |
+
event.preventDefault();
|
12 |
+
|
13 |
+
const token = tokenInput.value;
|
14 |
+
if (!token) return;
|
15 |
+
|
16 |
+
loadingContainer.classList.add("show"); // to show the loading animation
|
17 |
+
|
18 |
+
const loginResponse = await fetch(`/login?token=${token}`, {
|
19 |
+
method: "POST",
|
20 |
+
});
|
21 |
+
|
22 |
+
const loginData = await loginResponse.json();
|
23 |
+
|
24 |
+
if ("redirect" in loginData) {
|
25 |
+
// if the login response contains a "redirect" property, it means the login was successful
|
26 |
+
const initResp = await fetch(`initLlamaIndex?token=${token}`, {
|
27 |
+
method: "POST",
|
28 |
+
});
|
29 |
+
|
30 |
+
const initData = await initResp.json();
|
31 |
+
|
32 |
+
if ("success" in initData) {
|
33 |
+
window.location.href = loginData.redirect;
|
34 |
+
}
|
35 |
+
} else if ("error" in loginData) {
|
36 |
+
// display error message login page
|
37 |
+
loadingContainer.classList.remove("show");
|
38 |
+
}
|
39 |
+
});
|
static/styles/{chat.css β chatbot.css}
RENAMED
File without changes
|
static/styles/login.css
CHANGED
@@ -40,4 +40,35 @@ body {
|
|
40 |
/* Style error messages */
|
41 |
.error-message {
|
42 |
color: red;
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
43 |
}
|
|
|
40 |
/* Style error messages */
|
41 |
.error-message {
|
42 |
color: red;
|
43 |
+
}
|
44 |
+
|
45 |
+
/* Style loading */
|
46 |
+
.loading-container {
|
47 |
+
display: none;
|
48 |
+
justify-content: center;
|
49 |
+
align-items: center;
|
50 |
+
position: fixed;
|
51 |
+
top: 0;
|
52 |
+
left: 0;
|
53 |
+
right: 0;
|
54 |
+
bottom: 0;
|
55 |
+
background-color: rgba(255, 255, 255, 0.8);
|
56 |
+
z-index: 9999;
|
57 |
+
}
|
58 |
+
|
59 |
+
.loading-container.show {
|
60 |
+
display: flex;
|
61 |
+
}
|
62 |
+
|
63 |
+
.loader {
|
64 |
+
display: flex;
|
65 |
+
flex-direction: column;
|
66 |
+
justify-content: center;
|
67 |
+
align-items: center;
|
68 |
+
gap: 20px;
|
69 |
+
}
|
70 |
+
|
71 |
+
.loader img {
|
72 |
+
width: 60px;
|
73 |
+
height: 60px;
|
74 |
}
|
templates/base.html
CHANGED
@@ -6,9 +6,11 @@
|
|
6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7 |
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
8 |
<title>{% block title %}{% endblock %}</title>
|
9 |
-
<link rel="stylesheet" href="{{ url_for('static', path='styles/
|
10 |
<link rel="stylesheet" href="{{ url_for('static', path='styles/login.css') }}">
|
11 |
-
<script type="module" src="../static/
|
|
|
|
|
12 |
</head>
|
13 |
|
14 |
<body>
|
|
|
6 |
<meta name="viewport" content="width=device-width, initial-scale=1.0">
|
7 |
<meta http-equiv="X-UA-Compatible" content="ie=edge">
|
8 |
<title>{% block title %}{% endblock %}</title>
|
9 |
+
<link rel="stylesheet" href="{{ url_for('static', path='styles/chatbot.css') }}">
|
10 |
<link rel="stylesheet" href="{{ url_for('static', path='styles/login.css') }}">
|
11 |
+
<script type="module" src="../static/scripts/chatbot.js"></script>
|
12 |
+
<script type="module" src="../static/scripts/login.js"></script>
|
13 |
+
|
14 |
</head>
|
15 |
|
16 |
<body>
|
templates/{chat.html β chatbot.html}
RENAMED
@@ -7,7 +7,7 @@
|
|
7 |
<section class="msger">
|
8 |
<header class="msger-header">
|
9 |
<div class="msger-header-title">
|
10 |
-
<i class="
|
11 |
</div>
|
12 |
</header>
|
13 |
|
@@ -19,22 +19,21 @@
|
|
19 |
<div class="msg-bubble">
|
20 |
<div class="msg-info">
|
21 |
<div class="msg-info-name">Chatbot</div>
|
22 |
-
<div class="msg-info-time"
|
23 |
</div>
|
24 |
|
25 |
<div class="msg-text">
|
26 |
-
Hi, welcome to ChatBot!
|
27 |
</div>
|
28 |
</div>
|
29 |
</div>
|
30 |
|
31 |
</main>
|
32 |
|
33 |
-
<form class="msger-inputarea"
|
34 |
<input type="text" class="msger-input" id="textInput" placeholder="Enter your message...">
|
35 |
<button type="submit" class="msger-send-btn">Send</button>
|
36 |
</form>
|
37 |
</section>
|
38 |
<!-- partial -->
|
39 |
-
<script src='https://use.fontawesome.com/releases/v5.0.13/js/all.js'></script>
|
40 |
{% endblock %}
|
|
|
7 |
<section class="msger">
|
8 |
<header class="msger-header">
|
9 |
<div class="msger-header-title">
|
10 |
+
<i class="fa-thin fa-message-bot"></i>Water Regulation QA Chatbot <i class="fa-thin fa-message-bot"></i>
|
11 |
</div>
|
12 |
</header>
|
13 |
|
|
|
19 |
<div class="msg-bubble">
|
20 |
<div class="msg-info">
|
21 |
<div class="msg-info-name">Chatbot</div>
|
22 |
+
<div class="msg-info-time"></div>
|
23 |
</div>
|
24 |
|
25 |
<div class="msg-text">
|
26 |
+
Hi, welcome to ChatBot! Please type in your question. π
|
27 |
</div>
|
28 |
</div>
|
29 |
</div>
|
30 |
|
31 |
</main>
|
32 |
|
33 |
+
<form class="msger-inputarea">
|
34 |
<input type="text" class="msger-input" id="textInput" placeholder="Enter your message...">
|
35 |
<button type="submit" class="msger-send-btn">Send</button>
|
36 |
</form>
|
37 |
</section>
|
38 |
<!-- partial -->
|
|
|
39 |
{% endblock %}
|
templates/login.html
CHANGED
@@ -5,19 +5,21 @@
|
|
5 |
{% block content %}
|
6 |
<div class="login-box">
|
7 |
<h2 style="text-align: center">Login</h2>
|
8 |
-
{% if error %}
|
9 |
-
<p class="error-message">{{ error }}</p>
|
10 |
-
{% endif %}
|
11 |
|
12 |
-
<form
|
13 |
<label for="username">Username</label>
|
14 |
<input type="text" id="username" name="username" placeholder="Enter username" required>
|
15 |
|
16 |
-
<label for="accessToken">
|
17 |
-
<input type="password" id="
|
18 |
|
19 |
<button type="submit" class="login-button">Login</button>
|
20 |
</form>
|
21 |
</div>
|
22 |
-
|
|
|
|
|
|
|
|
|
|
|
23 |
{% endblock %}
|
|
|
5 |
{% block content %}
|
6 |
<div class="login-box">
|
7 |
<h2 style="text-align: center">Login</h2>
|
|
|
|
|
|
|
8 |
|
9 |
+
<form class="login-form" id="loginForm">
|
10 |
<label for="username">Username</label>
|
11 |
<input type="text" id="username" name="username" placeholder="Enter username" required>
|
12 |
|
13 |
+
<label for="accessToken">OpenAI API KEY</label>
|
14 |
+
<input type="password" class="token-input" id="accessToken" name="accessToken" placeholder="Enter Token Key" required>
|
15 |
|
16 |
<button type="submit" class="login-button">Login</button>
|
17 |
</form>
|
18 |
</div>
|
19 |
+
<div class="loading-container">
|
20 |
+
<div class="loader">
|
21 |
+
<p>Authenticating OpenAI Token ...</p>
|
22 |
+
<p>Initializing chatbot ...</p>
|
23 |
+
</div>
|
24 |
+
</div>
|
25 |
{% endblock %}
|