Spaces:
Running
Running
bigger changes
Browse files- .gitattributes +0 -35
- .github/workflows/air-quality-daily.yml +0 -39
- .github/workflows/huggingface-sync.yml +1 -1
- .gitignore +1 -0
- app_streamlit.py +0 -2
- debug.ipynb +2 -2
- dummy.txt +0 -28
- functions/figure.py +1 -1
- merge_df.py → functions/merge_df.py +0 -0
- img/pm25_forecast.png +0 -0
- infer.py +0 -102
- outcome_df.pkl +0 -3
- requirements.txt +0 -3
- schedule.py +0 -39
.gitattributes
DELETED
@@ -1,35 +0,0 @@
|
|
1 |
-
*.7z filter=lfs diff=lfs merge=lfs -text
|
2 |
-
*.arrow filter=lfs diff=lfs merge=lfs -text
|
3 |
-
*.bin filter=lfs diff=lfs merge=lfs -text
|
4 |
-
*.bz2 filter=lfs diff=lfs merge=lfs -text
|
5 |
-
*.ckpt filter=lfs diff=lfs merge=lfs -text
|
6 |
-
*.ftz filter=lfs diff=lfs merge=lfs -text
|
7 |
-
*.gz filter=lfs diff=lfs merge=lfs -text
|
8 |
-
*.h5 filter=lfs diff=lfs merge=lfs -text
|
9 |
-
*.joblib filter=lfs diff=lfs merge=lfs -text
|
10 |
-
*.lfs.* filter=lfs diff=lfs merge=lfs -text
|
11 |
-
*.mlmodel filter=lfs diff=lfs merge=lfs -text
|
12 |
-
*.model filter=lfs diff=lfs merge=lfs -text
|
13 |
-
*.msgpack filter=lfs diff=lfs merge=lfs -text
|
14 |
-
*.npy filter=lfs diff=lfs merge=lfs -text
|
15 |
-
*.npz filter=lfs diff=lfs merge=lfs -text
|
16 |
-
*.onnx filter=lfs diff=lfs merge=lfs -text
|
17 |
-
*.ot filter=lfs diff=lfs merge=lfs -text
|
18 |
-
*.parquet filter=lfs diff=lfs merge=lfs -text
|
19 |
-
*.pb filter=lfs diff=lfs merge=lfs -text
|
20 |
-
*.pickle filter=lfs diff=lfs merge=lfs -text
|
21 |
-
*.pkl filter=lfs diff=lfs merge=lfs -text
|
22 |
-
*.pt filter=lfs diff=lfs merge=lfs -text
|
23 |
-
*.pth filter=lfs diff=lfs merge=lfs -text
|
24 |
-
*.rar filter=lfs diff=lfs merge=lfs -text
|
25 |
-
*.safetensors filter=lfs diff=lfs merge=lfs -text
|
26 |
-
saved_model/**/* filter=lfs diff=lfs merge=lfs -text
|
27 |
-
*.tar.* filter=lfs diff=lfs merge=lfs -text
|
28 |
-
*.tar filter=lfs diff=lfs merge=lfs -text
|
29 |
-
*.tflite filter=lfs diff=lfs merge=lfs -text
|
30 |
-
*.tgz filter=lfs diff=lfs merge=lfs -text
|
31 |
-
*.wasm filter=lfs diff=lfs merge=lfs -text
|
32 |
-
*.xz filter=lfs diff=lfs merge=lfs -text
|
33 |
-
*.zip filter=lfs diff=lfs merge=lfs -text
|
34 |
-
*.zst filter=lfs diff=lfs merge=lfs -text
|
35 |
-
*tfevents* filter=lfs diff=lfs merge=lfs -text
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.github/workflows/air-quality-daily.yml
DELETED
@@ -1,39 +0,0 @@
|
|
1 |
-
# name: air-quality-daily
|
2 |
-
|
3 |
-
# on:
|
4 |
-
# schedule:
|
5 |
-
# - cron: "*/5 * * * *" # Run every 5 minutes (minimum allowed)
|
6 |
-
|
7 |
-
# jobs:
|
8 |
-
# schedule_pipelines:
|
9 |
-
# runs-on: ubuntu-latest
|
10 |
-
|
11 |
-
# permissions:
|
12 |
-
# pages: write
|
13 |
-
# contents: write
|
14 |
-
|
15 |
-
# steps:
|
16 |
-
# - name: checkout repo content
|
17 |
-
# uses: actions/checkout@v4
|
18 |
-
|
19 |
-
# - name: Update dummy file
|
20 |
-
# run: echo "$(date)" >> dummy.txt
|
21 |
-
|
22 |
-
|
23 |
-
# - name: pushing changes
|
24 |
-
# uses: stefanzweifel/git-auto-commit-action@v5
|
25 |
-
# with:
|
26 |
-
# commit_message: "Updating dashboard"
|
27 |
-
# commit_options: '--no-verify --signoff'
|
28 |
-
|
29 |
-
# repository: .
|
30 |
-
|
31 |
-
# status_options: '--untracked-files=no'
|
32 |
-
|
33 |
-
# skip_dirty_check: true
|
34 |
-
|
35 |
-
# skip_fetch: true
|
36 |
-
|
37 |
-
# skip_checkout: true
|
38 |
-
|
39 |
-
# push_options: '--force'
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
.github/workflows/huggingface-sync.yml
CHANGED
@@ -9,7 +9,7 @@ jobs:
|
|
9 |
sync-to-hub:
|
10 |
runs-on: ubuntu-latest
|
11 |
steps:
|
12 |
-
- uses: actions/checkout@
|
13 |
with:
|
14 |
fetch-depth: 0
|
15 |
lfs: true
|
|
|
9 |
sync-to-hub:
|
10 |
runs-on: ubuntu-latest
|
11 |
steps:
|
12 |
+
- uses: actions/checkout@v3
|
13 |
with:
|
14 |
fetch-depth: 0
|
15 |
lfs: true
|
.gitignore
CHANGED
@@ -3,3 +3,4 @@
|
|
3 |
.env
|
4 |
.cache.sqlite
|
5 |
__pycache__/
|
|
|
|
3 |
.env
|
4 |
.cache.sqlite
|
5 |
__pycache__/
|
6 |
+
debug.ipynb
|
app_streamlit.py
CHANGED
@@ -9,8 +9,6 @@ import pickle
|
|
9 |
import plotly.express as px
|
10 |
import json
|
11 |
from datetime import datetime
|
12 |
-
from apscheduler.schedulers.background import BackgroundScheduler
|
13 |
-
from huggingface_hub import restart_space
|
14 |
import os
|
15 |
|
16 |
|
|
|
9 |
import plotly.express as px
|
10 |
import json
|
11 |
from datetime import datetime
|
|
|
|
|
12 |
import os
|
13 |
|
14 |
|
debug.ipynb
CHANGED
@@ -2,7 +2,7 @@
|
|
2 |
"cells": [
|
3 |
{
|
4 |
"cell_type": "code",
|
5 |
-
"execution_count":
|
6 |
"metadata": {},
|
7 |
"outputs": [
|
8 |
{
|
@@ -55,7 +55,7 @@
|
|
55 |
},
|
56 |
{
|
57 |
"cell_type": "code",
|
58 |
-
"execution_count":
|
59 |
"metadata": {},
|
60 |
"outputs": [
|
61 |
{
|
|
|
2 |
"cells": [
|
3 |
{
|
4 |
"cell_type": "code",
|
5 |
+
"execution_count": 5,
|
6 |
"metadata": {},
|
7 |
"outputs": [
|
8 |
{
|
|
|
55 |
},
|
56 |
{
|
57 |
"cell_type": "code",
|
58 |
+
"execution_count": 3,
|
59 |
"metadata": {},
|
60 |
"outputs": [
|
61 |
{
|
dummy.txt
DELETED
@@ -1,28 +0,0 @@
|
|
1 |
-
Wed Nov 20 12:42:00 UTC 2024
|
2 |
-
Wed Nov 20 13:24:46 UTC 2024
|
3 |
-
Wed Nov 20 13:40:30 UTC 2024
|
4 |
-
Wed Nov 20 13:47:42 UTC 2024
|
5 |
-
Wed Nov 20 13:54:50 UTC 2024
|
6 |
-
Wed Nov 20 14:09:39 UTC 2024
|
7 |
-
Wed Nov 20 14:30:34 UTC 2024
|
8 |
-
Wed Nov 20 14:43:23 UTC 2024
|
9 |
-
Wed Nov 20 14:50:17 UTC 2024
|
10 |
-
Wed Nov 20 14:57:42 UTC 2024
|
11 |
-
Wed Nov 20 15:16:57 UTC 2024
|
12 |
-
Wed Nov 20 15:33:10 UTC 2024
|
13 |
-
Wed Nov 20 15:44:06 UTC 2024
|
14 |
-
Wed Nov 20 15:51:16 UTC 2024
|
15 |
-
Wed Nov 20 15:58:29 UTC 2024
|
16 |
-
Wed Nov 20 16:22:33 UTC 2024
|
17 |
-
Wed Nov 20 16:43:26 UTC 2024
|
18 |
-
Wed Nov 20 16:54:17 UTC 2024
|
19 |
-
Wed Nov 20 17:08:24 UTC 2024
|
20 |
-
Wed Nov 20 17:28:09 UTC 2024
|
21 |
-
Wed Nov 20 17:38:56 UTC 2024
|
22 |
-
Wed Nov 20 17:46:05 UTC 2024
|
23 |
-
Wed Nov 20 17:53:24 UTC 2024
|
24 |
-
Wed Nov 20 18:09:58 UTC 2024
|
25 |
-
Wed Nov 20 18:36:12 UTC 2024
|
26 |
-
Wed Nov 20 18:49:16 UTC 2024
|
27 |
-
Wed Nov 20 18:56:21 UTC 2024
|
28 |
-
Wed Nov 20 19:10:45 UTC 2024
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
functions/figure.py
CHANGED
@@ -109,7 +109,7 @@ def plot(df, n=10):
|
|
109 |
),
|
110 |
autosize=True,
|
111 |
width=2100,
|
112 |
-
height=
|
113 |
hoverlabel=dict(
|
114 |
font_size=20 # Increase hover label font size
|
115 |
)
|
|
|
109 |
),
|
110 |
autosize=True,
|
111 |
width=2100,
|
112 |
+
height=750,
|
113 |
hoverlabel=dict(
|
114 |
font_size=20 # Increase hover label font size
|
115 |
)
|
merge_df.py → functions/merge_df.py
RENAMED
File without changes
|
img/pm25_forecast.png
DELETED
Binary file (43.1 kB)
|
|
infer.py
DELETED
@@ -1,102 +0,0 @@
|
|
1 |
-
import datetime
|
2 |
-
import pandas as pd
|
3 |
-
from xgboost import XGBRegressor
|
4 |
-
import hopsworks
|
5 |
-
import json
|
6 |
-
from functions import util
|
7 |
-
import os
|
8 |
-
|
9 |
-
# Set up
|
10 |
-
|
11 |
-
api_key = os.getenv('HOPSWORKS_API_KEY')
|
12 |
-
project_name = os.getenv('HOPSWORKS_PROJECT')
|
13 |
-
|
14 |
-
project = hopsworks.login(project=project_name, api_key_value=api_key)
|
15 |
-
fs = project.get_feature_store()
|
16 |
-
secrets = util.secrets_api(project.name)
|
17 |
-
location_str = secrets.get_secret("SENSOR_LOCATION_JSON").value
|
18 |
-
location = json.loads(location_str)
|
19 |
-
country=location['country']
|
20 |
-
city=location['city']
|
21 |
-
street=location['street']
|
22 |
-
|
23 |
-
AQI_API_KEY = secrets.get_secret("AQI_API_KEY").value
|
24 |
-
location_str = secrets.get_secret("SENSOR_LOCATION_JSON").value
|
25 |
-
location = json.loads(location_str)
|
26 |
-
|
27 |
-
today = datetime.datetime.now() - datetime.timedelta(0)
|
28 |
-
|
29 |
-
feature_view = fs.get_feature_view(
|
30 |
-
name='air_quality_fv',
|
31 |
-
version=1,
|
32 |
-
)
|
33 |
-
|
34 |
-
### Retreive model
|
35 |
-
|
36 |
-
mr = project.get_model_registry()
|
37 |
-
|
38 |
-
retrieved_model = mr.get_model(
|
39 |
-
name="air_quality_xgboost_model",
|
40 |
-
version=1,
|
41 |
-
)
|
42 |
-
|
43 |
-
saved_model_dir = retrieved_model.download()
|
44 |
-
retrieved_xgboost_model = XGBRegressor()
|
45 |
-
retrieved_xgboost_model.load_model(saved_model_dir + "/model.json")
|
46 |
-
|
47 |
-
### Retrieve features
|
48 |
-
|
49 |
-
weather_fg = fs.get_feature_group(
|
50 |
-
name='weather',
|
51 |
-
version=1,
|
52 |
-
)
|
53 |
-
|
54 |
-
today_timestamp = pd.to_datetime(today)
|
55 |
-
batch_data = weather_fg.filter(weather_fg.date >= today_timestamp ).read()
|
56 |
-
|
57 |
-
|
58 |
-
### Predict and upload
|
59 |
-
|
60 |
-
batch_data['predicted_pm25'] = retrieved_xgboost_model.predict(
|
61 |
-
batch_data[['temperature_2m_mean', 'precipitation_sum', 'wind_speed_10m_max', 'wind_direction_10m_dominant']])
|
62 |
-
|
63 |
-
batch_data['street'] = street
|
64 |
-
batch_data['city'] = city
|
65 |
-
batch_data['country'] = country
|
66 |
-
# Fill in the number of days before the date on which you made the forecast (base_date)
|
67 |
-
batch_data['days_before_forecast_day'] = range(1, len(batch_data)+1)
|
68 |
-
batch_data = batch_data.sort_values(by=['date'])
|
69 |
-
#batch_data['date'] = batch_data['date'].dt.tz_convert(None).astype('datetime64[ns]')
|
70 |
-
|
71 |
-
plt = util.plot_air_quality_forecast(city, street, batch_data, file_path="./img/pm25_forecast.png")
|
72 |
-
|
73 |
-
monitor_fg = fs.get_or_create_feature_group(
|
74 |
-
name='aq_predictions',
|
75 |
-
description='Air Quality prediction monitoring',
|
76 |
-
version=1,
|
77 |
-
primary_key=['city','street','date','days_before_forecast_day'],
|
78 |
-
event_time="date"
|
79 |
-
)
|
80 |
-
|
81 |
-
print(f"Batch data: {batch_data}")
|
82 |
-
|
83 |
-
monitor_fg.insert(batch_data, write_options={"wait_for_job": True})
|
84 |
-
monitoring_df = monitor_fg.filter(monitor_fg.days_before_forecast_day == 1).read()
|
85 |
-
|
86 |
-
# Hindcast monitoring
|
87 |
-
|
88 |
-
air_quality_fg = fs.get_feature_group(
|
89 |
-
name='air_quality',
|
90 |
-
version=1,
|
91 |
-
)
|
92 |
-
air_quality_df = air_quality_fg.read()
|
93 |
-
|
94 |
-
outcome_df = air_quality_df[['date', 'pm25']]
|
95 |
-
preds_df = monitoring_df[['date', 'predicted_pm25']]
|
96 |
-
hindcast_df = pd.merge(preds_df, outcome_df, on="date")
|
97 |
-
hindcast_df = hindcast_df.sort_values(by=['date'])
|
98 |
-
|
99 |
-
if len(hindcast_df) == 0:
|
100 |
-
hindcast_df = util.backfill_predictions_for_monitoring(weather_fg, air_quality_df, monitor_fg, retrieved_xgboost_model)
|
101 |
-
|
102 |
-
plt = util.plot_air_quality_forecast(city, street, hindcast_df, file_path="./img/pm25_hindcast_1day.png", hindcast=True)
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
outcome_df.pkl
DELETED
@@ -1,3 +0,0 @@
|
|
1 |
-
version https://git-lfs.github.com/spec/v1
|
2 |
-
oid sha256:72e00d86aa97c8335b0ee61c6810ae6c5c0602dede91950641f5da0eec829b9a
|
3 |
-
size 40620
|
|
|
|
|
|
|
|
requirements.txt
CHANGED
@@ -21,9 +21,6 @@ matplotlib==3.8.3
|
|
21 |
|
22 |
hopsworks
|
23 |
pandas
|
24 |
-
#modal
|
25 |
streamlit
|
26 |
plotly
|
27 |
-
|
28 |
-
apscheduler
|
29 |
huggingface_hub
|
|
|
21 |
|
22 |
hopsworks
|
23 |
pandas
|
|
|
24 |
streamlit
|
25 |
plotly
|
|
|
|
|
26 |
huggingface_hub
|
schedule.py
DELETED
@@ -1,39 +0,0 @@
|
|
1 |
-
import modal
|
2 |
-
import requests
|
3 |
-
import os
|
4 |
-
import sys
|
5 |
-
|
6 |
-
image = (
|
7 |
-
modal.Image.debian_slim(python_version="3.10")
|
8 |
-
.pip_install("requests","python-dotenv")
|
9 |
-
)
|
10 |
-
|
11 |
-
app = modal.App("build-scheduler",image=image)
|
12 |
-
SPACE_ID = "Robzy/hbg-weather" # Replace with your Space ID
|
13 |
-
|
14 |
-
# Define a Modal function
|
15 |
-
@app.function(schedule=modal.Period(hours=0, minutes=2),
|
16 |
-
secrets=[modal.Secret.from_dotenv()]) # Run every 2 minutes
|
17 |
-
def trigger_rebuild():
|
18 |
-
import os
|
19 |
-
import requests
|
20 |
-
|
21 |
-
token = os.environ['HF_TOKEN'] # Your Hugging Face token
|
22 |
-
repo_id = "Robzy/hbg-weather" # Replace with your Space's repo ID
|
23 |
-
|
24 |
-
headers = {
|
25 |
-
"Authorization": f"Bearer {token}",
|
26 |
-
"Content-Type": "application/json"
|
27 |
-
}
|
28 |
-
|
29 |
-
url = f"https://api.huggingface.co/spaces/{repo_id}/rebuild"
|
30 |
-
|
31 |
-
response = requests.post(url, headers=headers)
|
32 |
-
|
33 |
-
if response.status_code == 200:
|
34 |
-
print("Space rebuild triggered successfully!")
|
35 |
-
else:
|
36 |
-
print(f"Failed to trigger rebuild: {response.status_code}, {response.text}")
|
37 |
-
|
38 |
-
if __name__ == "__main__":
|
39 |
-
trigger_rebuild()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|