Spaces:
Paused
Paused
ajout demande ville
Browse files- Notebook_Ferro.ipynb +16 -1
- Weather.json +5 -0
- app.py +107 -104
- user_location.json +1 -0
- weather.py +41 -0
Notebook_Ferro.ipynb
CHANGED
@@ -31,6 +31,21 @@
|
|
31 |
"load_dotenv()"
|
32 |
]
|
33 |
},
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
34 |
{
|
35 |
"cell_type": "code",
|
36 |
"execution_count": 57,
|
@@ -361,7 +376,7 @@
|
|
361 |
"name": "python",
|
362 |
"nbconvert_exporter": "python",
|
363 |
"pygments_lexer": "ipython3",
|
364 |
-
"version": "3.11.
|
365 |
}
|
366 |
},
|
367 |
"nbformat": 4,
|
|
|
31 |
"load_dotenv()"
|
32 |
]
|
33 |
},
|
34 |
+
{
|
35 |
+
"cell_type": "code",
|
36 |
+
"execution_count": 2,
|
37 |
+
"metadata": {},
|
38 |
+
"outputs": [
|
39 |
+
{
|
40 |
+
"name": "stdout",
|
41 |
+
"output_type": "stream",
|
42 |
+
"text": [
|
43 |
+
"Today's date: 2024-02-26\n"
|
44 |
+
]
|
45 |
+
}
|
46 |
+
],
|
47 |
+
"source": []
|
48 |
+
},
|
49 |
{
|
50 |
"cell_type": "code",
|
51 |
"execution_count": 57,
|
|
|
376 |
"name": "python",
|
377 |
"nbconvert_exporter": "python",
|
378 |
"pygments_lexer": "ipython3",
|
379 |
+
"version": "3.11.4"
|
380 |
}
|
381 |
},
|
382 |
"nbformat": 4,
|
Weather.json
ADDED
@@ -0,0 +1,5 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
{
|
2 |
+
"temperature": 20,
|
3 |
+
"humidity": 60,
|
4 |
+
"pression": 1000
|
5 |
+
}
|
app.py
CHANGED
@@ -2,8 +2,6 @@ import os
|
|
2 |
import sys
|
3 |
from datetime import datetime
|
4 |
from pathlib import Path
|
5 |
-
|
6 |
-
import gradio as gr
|
7 |
import plotly.graph_objects as go
|
8 |
import uvicorn
|
9 |
from dotenv import load_dotenv
|
@@ -13,7 +11,13 @@ from mistralai.client import ChatMessage, MistralClient
|
|
13 |
from pydantic import BaseModel
|
14 |
from fastapi import Depends
|
15 |
import json
|
16 |
-
from fastapi.responses import HTMLResponse
|
|
|
|
|
|
|
|
|
|
|
|
|
17 |
|
18 |
|
19 |
# Load environment variables
|
@@ -42,39 +46,8 @@ app.mount("/static", StaticFiles(directory=static_dir), name="static")
|
|
42 |
|
43 |
# Gradio stuff
|
44 |
|
45 |
-
|
46 |
-
|
47 |
-
file_path = static_dir / file_name
|
48 |
-
print(file_path)
|
49 |
-
with open(file_path, "w") as f:
|
50 |
-
f.write(f"""
|
51 |
-
<script src="https://cdn.tailwindcss.com"></script>
|
52 |
-
<body class="bg-gray-200 dark:text-white dark:bg-gray-900">
|
53 |
-
<h1 class="text-3xl font-bold">
|
54 |
-
Hello <i>{text_input}</i> From Gradio Iframe
|
55 |
-
</h1>
|
56 |
-
<h3>Filename: {file_name}</h3>
|
57 |
-
""")
|
58 |
-
iframe = f"""<iframe src="/static/{file_name}" width="100%" height="500px"></iframe>"""
|
59 |
-
link = f'<a href="/static/{file_name}" target="_blank">{file_name}</a>'
|
60 |
-
return link, iframe
|
61 |
-
|
62 |
-
|
63 |
-
with gr.Blocks() as block:
|
64 |
-
gr.Markdown("""
|
65 |
-
## Gradio + FastAPI + Static Server
|
66 |
-
This is a demo of how to use Gradio with FastAPI and a static server.
|
67 |
-
The Gradio app generates dynamic HTML files and stores them in a static directory. FastAPI serves the static files.
|
68 |
-
""")
|
69 |
-
with gr.Row():
|
70 |
-
with gr.Column():
|
71 |
-
text_input = gr.Textbox(label="Name")
|
72 |
-
markdown = gr.Markdown(label="Output Box")
|
73 |
-
new_btn = gr.Button("New")
|
74 |
-
with gr.Column():
|
75 |
-
html = gr.HTML(label="HTML preview", show_label=True)
|
76 |
-
|
77 |
-
new_btn.click(fn=predict, inputs=[text_input], outputs=[markdown, html])
|
78 |
|
79 |
|
80 |
def create_world_map(lat, lon):
|
@@ -104,21 +77,6 @@ def create_world_map(lat, lon):
|
|
104 |
return fig
|
105 |
|
106 |
|
107 |
-
# # Fake JSON data for the user profile
|
108 |
-
# user_profile_data = {
|
109 |
-
# "name": "John Doe",
|
110 |
-
# "age": 30,
|
111 |
-
# "location": "Montreal",
|
112 |
-
# "lat": 45.5017,
|
113 |
-
# "lon": -73.5673
|
114 |
-
# }
|
115 |
-
|
116 |
-
# #as a JSON:
|
117 |
-
# with open('user_profile.json', 'w') as f:
|
118 |
-
# json.dump(user_profile_data, f)
|
119 |
-
|
120 |
-
# Mistral AI Chat
|
121 |
-
|
122 |
def chat_with_mistral(user_input):
|
123 |
messages = [ChatMessage(role="user", content=user_input)]
|
124 |
|
@@ -126,36 +84,6 @@ def chat_with_mistral(user_input):
|
|
126 |
return chat_response.choices[0].message.content
|
127 |
|
128 |
|
129 |
-
### FRONTEND ###
|
130 |
-
def create_gradio_dashboard():
|
131 |
-
with gr.Blocks() as demo:
|
132 |
-
# Mistral AI Chat
|
133 |
-
with gr.Column():
|
134 |
-
with gr.Row():
|
135 |
-
user_input = gr.Textbox (lines=2, placeholder=placeholder)
|
136 |
-
send_chat_btn = gr.Button(value="Send")
|
137 |
-
update_map_btn = gr.Button(value="Update Map")
|
138 |
-
chat_output = gr.Textbox(lines=2, placeholder="Réponse")
|
139 |
-
|
140 |
-
# Profile
|
141 |
-
with gr.Row():
|
142 |
-
name = gr.Textbox(label="Name")
|
143 |
-
age = gr.Number(label="Age")
|
144 |
-
location = gr.Textbox(label="Location")
|
145 |
-
lat = gr.Number(value=45.5017, label="Latitude")
|
146 |
-
lon = gr.Number(value=-73.5673, label="Longitude")
|
147 |
-
load_user_profile_btn = gr.Button(value="Load User Profile")
|
148 |
-
save_user_profile_btn = gr.Button(value="Save User Profile")
|
149 |
-
|
150 |
-
# Map
|
151 |
-
with gr.Row():
|
152 |
-
map = gr.Plot()
|
153 |
-
|
154 |
-
# Mistral AI Chat
|
155 |
-
demo.load(chat_with_mistral, user_input, chat_output)
|
156 |
-
send_chat_btn.click(chat_with_mistral, user_input, chat_output)
|
157 |
-
|
158 |
-
return demo
|
159 |
|
160 |
|
161 |
# Profile stuff
|
@@ -166,6 +94,16 @@ class UserProfile(BaseModel):
|
|
166 |
lat: float
|
167 |
lon: float
|
168 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
169 |
@app.post("/user_profile")
|
170 |
def save_user_profile(user_profile: UserProfile):
|
171 |
with open('user_profile.json', 'w') as f:
|
@@ -177,16 +115,38 @@ def load_user_profile():
|
|
177 |
with open('user_profile.json', 'r') as f:
|
178 |
user_profile = json.load(f)
|
179 |
return UserProfile(**user_profile)
|
180 |
-
|
181 |
@app.put("/user_profile")
|
182 |
def update_user_profile(user_profile: UserProfile):
|
183 |
with open('user_profile.json', 'w') as f:
|
184 |
json.dump(user_profile.dict(), f)
|
185 |
return user_profile
|
186 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
187 |
# load user profile on startup
|
188 |
user_profile = load_user_profile()
|
189 |
-
|
190 |
|
191 |
### BACKEND ###
|
192 |
@app.get("/meteo")
|
@@ -194,14 +154,57 @@ async def read_meteo(location: str, date: str):
|
|
194 |
# API call to get the weather
|
195 |
pass
|
196 |
|
197 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
198 |
@app.get("/", response_class=HTMLResponse)
|
199 |
-
async def
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
200 |
|
201 |
#1st : display as background the map of the user location:
|
202 |
# get the user location
|
203 |
lat = user_profile.lat
|
204 |
lon = user_profile.lon
|
|
|
|
|
|
|
205 |
# create the map
|
206 |
fig = create_world_map(lat, lon)
|
207 |
# save the map as a file
|
@@ -210,25 +213,25 @@ async def home(user_profile: UserProfile = Depends(load_user_profile)):
|
|
210 |
# display the map
|
211 |
map_html = f'<iframe src="/static/map.html" width="100%" height="500px"></iframe>'
|
212 |
|
213 |
-
|
214 |
-
# create the gradio dashboard
|
215 |
-
# gradio_dashboard = create_gradio_dashboard()
|
216 |
-
# save the dashboard as a file
|
217 |
-
# dashboard_file = static_dir / "dashboard.html"
|
218 |
-
# gradio_dashboard.save(dashboard_file)
|
219 |
-
# # display the dashboard
|
220 |
-
# dashboard_html = f'<iframe src="/static/dashboard.html" width="100%" height="500px"></iframe>'
|
221 |
-
|
222 |
return f"""
|
223 |
-
|
224 |
-
|
225 |
-
|
226 |
-
|
227 |
-
|
228 |
-
|
229 |
-
|
230 |
-
|
231 |
-
|
232 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
233 |
# <h2>Gradio Dashboard</h2>
|
234 |
# {dashboard_html}
|
|
|
2 |
import sys
|
3 |
from datetime import datetime
|
4 |
from pathlib import Path
|
|
|
|
|
5 |
import plotly.graph_objects as go
|
6 |
import uvicorn
|
7 |
from dotenv import load_dotenv
|
|
|
11 |
from pydantic import BaseModel
|
12 |
from fastapi import Depends
|
13 |
import json
|
14 |
+
from fastapi.responses import HTMLResponse, RedirectResponse, Response
|
15 |
+
from datetime import date
|
16 |
+
from weather import get_weather
|
17 |
+
|
18 |
+
# code that gives the date of today
|
19 |
+
today = date.today()
|
20 |
+
today = today.strftime("%Y-%m-%d")
|
21 |
|
22 |
|
23 |
# Load environment variables
|
|
|
46 |
|
47 |
# Gradio stuff
|
48 |
|
49 |
+
|
50 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
51 |
|
52 |
|
53 |
def create_world_map(lat, lon):
|
|
|
77 |
return fig
|
78 |
|
79 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
80 |
def chat_with_mistral(user_input):
|
81 |
messages = [ChatMessage(role="user", content=user_input)]
|
82 |
|
|
|
84 |
return chat_response.choices[0].message.content
|
85 |
|
86 |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
87 |
|
88 |
|
89 |
# Profile stuff
|
|
|
94 |
lat: float
|
95 |
lon: float
|
96 |
|
97 |
+
class UserLocation(BaseModel):
|
98 |
+
city: str
|
99 |
+
|
100 |
+
class Weather(BaseModel):
|
101 |
+
temperature: float
|
102 |
+
humidity: float
|
103 |
+
pression: float
|
104 |
+
|
105 |
+
|
106 |
+
|
107 |
@app.post("/user_profile")
|
108 |
def save_user_profile(user_profile: UserProfile):
|
109 |
with open('user_profile.json', 'w') as f:
|
|
|
115 |
with open('user_profile.json', 'r') as f:
|
116 |
user_profile = json.load(f)
|
117 |
return UserProfile(**user_profile)
|
|
|
118 |
@app.put("/user_profile")
|
119 |
def update_user_profile(user_profile: UserProfile):
|
120 |
with open('user_profile.json', 'w') as f:
|
121 |
json.dump(user_profile.dict(), f)
|
122 |
return user_profile
|
123 |
|
124 |
+
@app.get("/weather")
|
125 |
+
def load_weather():
|
126 |
+
with open('Weather.json', 'r') as f:
|
127 |
+
w = json.load(f)
|
128 |
+
return Weather(**w)
|
129 |
+
|
130 |
+
|
131 |
+
# @app.post("/user_location")
|
132 |
+
# async def set_user_location(user_location: UserLocation):
|
133 |
+
# # Save the user location as a JSON file
|
134 |
+
# with open('user_location.json', 'w') as f:
|
135 |
+
# json.dump(user_location.dict(), f)
|
136 |
+
# return RedirectResponse(url='/home')
|
137 |
+
|
138 |
+
@app.post("/user_location")
|
139 |
+
async def set_user_location(user_location: UserLocation):
|
140 |
+
# Save the user location as a JSON file
|
141 |
+
with open('user_location.json', 'w') as f:
|
142 |
+
json.dump(user_location.dict(), f)
|
143 |
+
response = Response(headers={"Location": "/home"})
|
144 |
+
response.status_code = 303
|
145 |
+
return response
|
146 |
+
|
147 |
# load user profile on startup
|
148 |
user_profile = load_user_profile()
|
149 |
+
weather=load_weather()
|
150 |
|
151 |
### BACKEND ###
|
152 |
@app.get("/meteo")
|
|
|
154 |
# API call to get the weather
|
155 |
pass
|
156 |
|
157 |
+
|
158 |
+
|
159 |
+
|
160 |
+
|
161 |
+
|
162 |
+
|
163 |
+
|
164 |
+
|
165 |
+
|
166 |
+
|
167 |
+
# On récupère les infos sur la ville. On les sauvegarde dans un fichier JSON
|
168 |
@app.get("/", response_class=HTMLResponse)
|
169 |
+
async def enter_location():
|
170 |
+
return """
|
171 |
+
<form id="locationForm">
|
172 |
+
<label for="city">Enter your city:</label><br>
|
173 |
+
<input type="text" id="city" name="city"><br>
|
174 |
+
<input type="submit" value="Submit">
|
175 |
+
</form>
|
176 |
+
<script>
|
177 |
+
document.getElementById('locationForm').addEventListener('submit', function(event) {
|
178 |
+
event.preventDefault();
|
179 |
+
var city = document.getElementById('city').value;
|
180 |
+
fetch('/user_location', {
|
181 |
+
method: 'POST',
|
182 |
+
headers: {
|
183 |
+
'Content-Type': 'application/json',
|
184 |
+
},
|
185 |
+
body: JSON.stringify({city: city}),
|
186 |
+
})
|
187 |
+
.then(response => {
|
188 |
+
if (response.redirected) {
|
189 |
+
window.location.href = '/home';
|
190 |
+
}
|
191 |
+
});
|
192 |
+
});
|
193 |
+
</script>
|
194 |
+
"""
|
195 |
+
|
196 |
+
|
197 |
+
# Home page : using the user profile, display the weather and chat with Mistral AI
|
198 |
+
@app.get("/home", response_class=HTMLResponse)
|
199 |
+
async def home(user_profile: UserProfile = Depends(load_user_profile), Weather: Weather = Depends(load_weather)):
|
200 |
|
201 |
#1st : display as background the map of the user location:
|
202 |
# get the user location
|
203 |
lat = user_profile.lat
|
204 |
lon = user_profile.lon
|
205 |
+
temperature = Weather.temperature
|
206 |
+
humidity = Weather.humidity
|
207 |
+
pression = Weather.pression
|
208 |
# create the map
|
209 |
fig = create_world_map(lat, lon)
|
210 |
# save the map as a file
|
|
|
213 |
# display the map
|
214 |
map_html = f'<iframe src="/static/map.html" width="100%" height="500px"></iframe>'
|
215 |
|
216 |
+
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
217 |
return f"""
|
218 |
+
<center>
|
219 |
+
<h1>Bienvenu !</h1></center>
|
220 |
+
<div style="display: flex;">
|
221 |
+
<div style="flex: 50%;">
|
222 |
+
<h2>Informations du jour</h2>
|
223 |
+
<p>temperature: {temperature}</p>
|
224 |
+
<p>humidity: {humidity}</p>
|
225 |
+
<p>pression: {pression}</p>
|
226 |
+
<h2>Map</h2>
|
227 |
+
{map_html}
|
228 |
+
|
229 |
+
</div>
|
230 |
+
<div style="flex: 50%;">
|
231 |
+
<h2>Avez-vous une question ?</h2>
|
232 |
+
<textarea style="width: 100%; height: 500px;"></textarea>
|
233 |
+
</div>
|
234 |
+
</div>
|
235 |
+
"""
|
236 |
# <h2>Gradio Dashboard</h2>
|
237 |
# {dashboard_html}
|
user_location.json
ADDED
@@ -0,0 +1 @@
|
|
|
|
|
1 |
+
{"city": "Lyon"}
|
weather.py
ADDED
@@ -0,0 +1,41 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
1 |
+
import requests
|
2 |
+
import json
|
3 |
+
import datetime
|
4 |
+
from pprint import pprint
|
5 |
+
from datetime import date
|
6 |
+
def get_weather(city, date):
|
7 |
+
agro_api_key = "88aaa872e29fedb008a2ffd240ebdf56"
|
8 |
+
opencage_api_key = "bade196e8eac4d33b72dba6d9e40285a"
|
9 |
+
|
10 |
+
# On récupère les lat et lon de la ville
|
11 |
+
geocode_url = f"https://api.opencagedata.com/geocode/v1/json?q={city}&key={opencage_api_key}"
|
12 |
+
geocode_response = requests.get(geocode_url)
|
13 |
+
geocode_data = geocode_response.json()
|
14 |
+
|
15 |
+
|
16 |
+
latitude = geocode_data['results'][0]['geometry']['lat']
|
17 |
+
longitude = geocode_data['results'][0]['geometry']['lng']
|
18 |
+
|
19 |
+
# On demande la météo pour cette ville
|
20 |
+
forecast_url = f"http://api.agromonitoring.com/agro/1.0/weather/forecast?lat={latitude}&lon={longitude}&appid={agro_api_key}"
|
21 |
+
forecast_response = requests.get(forecast_url)
|
22 |
+
|
23 |
+
if forecast_response.status_code == 200:
|
24 |
+
forecast_data = forecast_response.json()
|
25 |
+
d={}
|
26 |
+
for forecast in forecast_data:
|
27 |
+
datew = datetime.datetime.fromtimestamp(forecast['dt'])
|
28 |
+
temperature = forecast['main']['temp']
|
29 |
+
weather_description = forecast['weather'][0]['description']
|
30 |
+
|
31 |
+
if str(datew).split(' ')[0]==str(date) :
|
32 |
+
d[str(datew)]=f"Location : {city}, Temperature: {round(temperature-273.15,2)}°C, Weather: {weather_description}"
|
33 |
+
return d
|
34 |
+
else:
|
35 |
+
print(f"Error: {forecast_response.status_code}")
|
36 |
+
|
37 |
+
# #exemple
|
38 |
+
# today = date.today()
|
39 |
+
# today = today.strftime("%Y-%m-%d")
|
40 |
+
# a=get_weather('Paris',today)
|
41 |
+
# print(a)
|