Spaces:
Paused
Paused
Clément Simon
commited on
Commit
•
eb89bee
1
Parent(s):
c03a978
feat: refactoring HTML/CSS/JS
Browse files- app.py +71 -33
- static/layout.html +31 -0
- static/script.js +9 -0
- static/style.css +19 -0
- user_location.json +1 -1
app.py
CHANGED
@@ -5,7 +5,7 @@ from pathlib import Path
|
|
5 |
import plotly.graph_objects as go
|
6 |
import uvicorn
|
7 |
from dotenv import load_dotenv
|
8 |
-
from fastapi import FastAPI, Depends
|
9 |
from fastapi.staticfiles import StaticFiles
|
10 |
from mistralai.client import ChatMessage, MistralClient
|
11 |
from pydantic import BaseModel
|
@@ -13,6 +13,8 @@ import json
|
|
13 |
from fastapi.responses import HTMLResponse, RedirectResponse, Response
|
14 |
from datetime import date
|
15 |
from weather import get_weather
|
|
|
|
|
16 |
|
17 |
# code that gives the date of today
|
18 |
today = date.today()
|
@@ -42,9 +44,8 @@ static_dir.mkdir(parents=True, exist_ok=True)
|
|
42 |
# mount FastAPI StaticFiles server
|
43 |
app.mount("/static", StaticFiles(directory=static_dir), name="static")
|
44 |
|
45 |
-
|
46 |
-
|
47 |
-
|
48 |
|
49 |
|
50 |
|
@@ -153,16 +154,6 @@ async def set_user_location(user_location: UserLocation):
|
|
153 |
user_profile = load_user_profile()
|
154 |
weather=load_weather()
|
155 |
|
156 |
-
### BACKEND ###
|
157 |
-
@app.get("/meteo")
|
158 |
-
async def read_meteo(location: str, date: str):
|
159 |
-
# API call to get the weather
|
160 |
-
pass
|
161 |
-
|
162 |
-
|
163 |
-
|
164 |
-
|
165 |
-
|
166 |
@app.get("/", response_class=HTMLResponse)
|
167 |
async def enter_location():
|
168 |
return """
|
@@ -192,8 +183,11 @@ async def enter_location():
|
|
192 |
"""
|
193 |
# Home page : using the user profile, display the weather and chat with Mistral AI
|
194 |
@app.get("/home", response_class=HTMLResponse)
|
195 |
-
async def home(
|
196 |
-
|
|
|
|
|
|
|
197 |
|
198 |
with open('user_location.json', 'r') as f:
|
199 |
user_location = json.load(f)
|
@@ -220,23 +214,67 @@ async def home(user_profile: UserProfile = Depends(load_user_profile), weather:
|
|
220 |
map_file = static_dir / "map.html"
|
221 |
fig.write_html(str(map_file))
|
222 |
# display the map
|
223 |
-
map_html = f'<iframe src="/static/map.html" width="100%" height="
|
224 |
-
|
225 |
-
|
|
|
|
|
226 |
return f"""
|
227 |
-
|
228 |
-
|
229 |
-
<
|
230 |
-
|
231 |
-
|
232 |
-
|
233 |
-
|
234 |
-
|
235 |
-
{
|
236 |
-
|
237 |
-
|
238 |
-
|
239 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
240 |
</div>
|
|
|
|
|
|
|
|
|
|
|
241 |
</div>
|
242 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
5 |
import plotly.graph_objects as go
|
6 |
import uvicorn
|
7 |
from dotenv import load_dotenv
|
8 |
+
from fastapi import FastAPI, Depends, Request
|
9 |
from fastapi.staticfiles import StaticFiles
|
10 |
from mistralai.client import ChatMessage, MistralClient
|
11 |
from pydantic import BaseModel
|
|
|
13 |
from fastapi.responses import HTMLResponse, RedirectResponse, Response
|
14 |
from datetime import date
|
15 |
from weather import get_weather
|
16 |
+
from fastapi.templating import Jinja2Templates
|
17 |
+
|
18 |
|
19 |
# code that gives the date of today
|
20 |
today = date.today()
|
|
|
44 |
# mount FastAPI StaticFiles server
|
45 |
app.mount("/static", StaticFiles(directory=static_dir), name="static")
|
46 |
|
47 |
+
# templating
|
48 |
+
templates = Jinja2Templates(directory="static")
|
|
|
49 |
|
50 |
|
51 |
|
|
|
154 |
user_profile = load_user_profile()
|
155 |
weather=load_weather()
|
156 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
157 |
@app.get("/", response_class=HTMLResponse)
|
158 |
async def enter_location():
|
159 |
return """
|
|
|
183 |
"""
|
184 |
# Home page : using the user profile, display the weather and chat with Mistral AI
|
185 |
@app.get("/home", response_class=HTMLResponse)
|
186 |
+
async def home(
|
187 |
+
request: Request,
|
188 |
+
user_profile: UserProfile = Depends(load_user_profile),
|
189 |
+
weather: Weather = Depends(load_weather),
|
190 |
+
):
|
191 |
|
192 |
with open('user_location.json', 'r') as f:
|
193 |
user_location = json.load(f)
|
|
|
214 |
map_file = static_dir / "map.html"
|
215 |
fig.write_html(str(map_file))
|
216 |
# display the map
|
217 |
+
map_html = f'<iframe src="/static/map.html" width="100%" height="100%" ></iframe>'
|
218 |
+
|
219 |
+
|
220 |
+
return templates.TemplateResponse("layout.html", {"request": request, "user_profile": user_profile, "weather": weather, "map_html": map_html})
|
221 |
+
|
222 |
return f"""
|
223 |
+
<html>
|
224 |
+
<head>
|
225 |
+
<title>{title}</title>
|
226 |
+
</head>
|
227 |
+
<body>
|
228 |
+
|
229 |
+
<div id="leftMenu" class="side-menu">
|
230 |
+
<ul id="Profile">
|
231 |
+
<li>Name: {user_profile.name}</li>
|
232 |
+
<li>Age: {user_profile.age}</li>
|
233 |
+
<li>Location: {user_profile.location}</li>
|
234 |
+
</ul>
|
235 |
+
<button id="toggleMenu">Toggle Menu</button>
|
236 |
+
</div>
|
237 |
+
|
238 |
+
<div id="rightProfile" class="side-menu">
|
239 |
+
<div id="menu">
|
240 |
+
<h1>{title}</h1>
|
241 |
+
<p>{description}</p>
|
242 |
+
<input type="text" id="user_input" placeholder="{placeholder}">
|
243 |
+
<button onclick="sendChat()">Send</button>
|
244 |
+
<ul id="chat"></ul>
|
245 |
</div>
|
246 |
+
<button id="toggleProfile">Toggle Profile</button>
|
247 |
+
</div>
|
248 |
+
|
249 |
+
<div id="map">
|
250 |
+
{map_html}
|
251 |
</div>
|
252 |
+
|
253 |
+
<script>
|
254 |
+
function sendChat() {{
|
255 |
+
var user_input = document.getElementById("user_input").value;
|
256 |
+
var chat = document.getElementById("chat");
|
257 |
+
var user_message = document.createElement("li");
|
258 |
+
user_message.appendChild(document.createTextNode(user_input));
|
259 |
+
chat.appendChild(user_message);
|
260 |
+
document.getElementById("user_input").value = "";
|
261 |
+
fetch('/chat', {{
|
262 |
+
method: 'POST',
|
263 |
+
headers: {{
|
264 |
+
'Content-Type': 'application/json',
|
265 |
+
}},
|
266 |
+
body: JSON.stringify({{
|
267 |
+
user_input: user_input
|
268 |
+
}}),
|
269 |
+
}})
|
270 |
+
.then(response => response.json())
|
271 |
+
.then(data => {{
|
272 |
+
var mistral_message = document.createElement("li");
|
273 |
+
mistral_message.appendChild(document.createTextNode(data.mistral_response));
|
274 |
+
chat.appendChild(mistral_message);
|
275 |
+
}});
|
276 |
+
}}
|
277 |
+
</script>
|
278 |
+
</body>
|
279 |
+
</html>
|
280 |
+
"""
|
static/layout.html
ADDED
@@ -0,0 +1,31 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
<!DOCTYPE html>
|
2 |
+
<html>
|
3 |
+
<head>
|
4 |
+
<title>FastAPI Home</title>
|
5 |
+
<link rel="stylesheet" href="/static/style.css">
|
6 |
+
</head>
|
7 |
+
<body>
|
8 |
+
<div id="leftMenu" class="side-menu">
|
9 |
+
<ul id="Profile">
|
10 |
+
<li>Name: {{ user_profile.name }}</li>
|
11 |
+
<li>Age: {{ user_profile.age }}</li>
|
12 |
+
<li>Location: {{ user_profile.location }}</li>
|
13 |
+
</ul>
|
14 |
+
<button id="toggleMenu">Toggle Menu</button>
|
15 |
+
</div>
|
16 |
+
|
17 |
+
<div id="mainContent">
|
18 |
+
<!-- Main content here -->
|
19 |
+
<div id="map">
|
20 |
+
{{ map_html | safe }}
|
21 |
+
</div>
|
22 |
+
</div>
|
23 |
+
|
24 |
+
<div id="rightProfile" class="side-menu">
|
25 |
+
<!-- Profile content here -->
|
26 |
+
<button id="toggleProfile">Toggle Profile</button>
|
27 |
+
</div>
|
28 |
+
|
29 |
+
<script src="/static/script.js"></script>
|
30 |
+
</body>
|
31 |
+
</html>
|
static/script.js
ADDED
@@ -0,0 +1,9 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
document.getElementById('toggleMenu').addEventListener('click', function () {
|
2 |
+
var menu = document.getElementById('leftMenu');
|
3 |
+
menu.classList.toggle('hidden');
|
4 |
+
});
|
5 |
+
|
6 |
+
document.getElementById('toggleProfile').addEventListener('click', function () {
|
7 |
+
var profile = document.getElementById('rightProfile');
|
8 |
+
profile.classList.toggle('hidden');
|
9 |
+
});
|
static/style.css
ADDED
@@ -0,0 +1,19 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
.side-menu {
|
2 |
+
width: 200px; /* Fixed width */
|
3 |
+
position: fixed;
|
4 |
+
top: 0;
|
5 |
+
overflow: auto;
|
6 |
+
height: 100%;
|
7 |
+
}
|
8 |
+
|
9 |
+
#leftMenu {
|
10 |
+
left: 0;
|
11 |
+
}
|
12 |
+
|
13 |
+
#rightProfile {
|
14 |
+
right: 0;
|
15 |
+
}
|
16 |
+
|
17 |
+
.hidden {
|
18 |
+
display: none;
|
19 |
+
}
|
user_location.json
CHANGED
@@ -1 +1 @@
|
|
1 |
-
{"city": "
|
|
|
1 |
+
{"city": "Clamart"}
|