-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
120 lines (104 loc) · 4.23 KB
/
app.py
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
from flask import Flask, request
from datetime import datetime, timezone
import psycopg2
import os
CREATE_ROOMS_TABLE = (
"CREATE TABLE IF NOT EXISTS rooms (id SERIAL PRIMARY KEY, name TEXT);"
)
CREATE_TEMPS_TABLE = """CREATE TABLE IF NOT EXISTS temperatures (room_id INTEGER, temperature REAL,
date TIMESTAMP, FOREIGN KEY(room_id) REFERENCES rooms(id) ON DELETE CASCADE);"""
INSERT_ROOM_RETURN_ID = "INSERT INTO rooms (name) VALUES (%s) RETURNING id;"
INSERT_TEMP = (
"INSERT INTO temperatures (room_id, temperature, date) VALUES (%s, %s, %s);"
)
ROOM_NAME = """SELECT name FROM rooms WHERE id = (%s)"""
ROOM_NUMBER_OF_DAYS = """SELECT COUNT(DISTINCT DATE(date)) AS days FROM temperatures WHERE room_id = (%s);"""
ROOM_ALL_TIME_AVG = (
"SELECT AVG(temperature) as average FROM temperatures WHERE room_id = (%s);"
)
ROOM_TERM = """SELECT DATE(temperatures.date) as reading_date,
AVG(temperatures.temperature)
FROM temperatures
WHERE temperatures.room_id = (%s)
GROUP BY reading_date
HAVING DATE(temperatures.date) > (SELECT MAX(DATE(temperatures.date))-(%s) FROM temperatures);"""
GLOBAL_NUMBER_OF_DAYS = (
"""SELECT COUNT(DISTINCT DATE(date)) AS days FROM temperatures;"""
)
GLOBAL_AVG = """SELECT AVG(temperature) as average FROM temperatures;"""
url = os.environ.get("DATABASE_URL")
print("***URL*** = " + url)
connection = psycopg2.connect(url)
app = Flask(__name__)
@app.route('/')
def home():
return "Hello world"
# create a room in the database
# {"name": "Room name"}
@app.post("/api/room")
def create_room():
data = request.get_json()
name = data["name"]
with connection:
with connection.cursor() as cursor:
cursor.execute(CREATE_ROOMS_TABLE)
cursor.execute(INSERT_ROOM_RETURN_ID, (name,))
room_id = cursor.fetchone()[0]
return {"id": room_id, "message": f"Room {name} created."}, 201
# Add a temperature for a room id
# {"temperature": 15.9, "room": 2 "date": "%m-%d-%Y %H:%M:%S"} date is optional
@app.post("/api/temperature")
def add_temp():
data = request.get_json()
temperature = data["temperature"]
room_id = data["room"]
try:
date = datetime.strptime(data["date"], "%m-%d-%Y %H:%M:%S")
except KeyError:
date = datetime.now(timezone.utc)
with connection:
with connection.cursor() as cursor:
cursor.execute(CREATE_TEMPS_TABLE)
cursor.execute(INSERT_TEMP, (room_id, temperature, date))
return {"message": "Temperature added."}, 201
# Get the average temperature for a room since its creation
@app.get("/api/room/<int:room_id>")
def get_room_all(room_id):
args = request.args
term = args.get("term")
if term is not None:
return get_room_term(room_id, term)
else:
with connection:
with connection.cursor() as cursor:
cursor.execute(ROOM_NAME, (room_id,))
name = cursor.fetchone()[0]
cursor.execute(ROOM_ALL_TIME_AVG, (room_id,))
average = cursor.fetchone()[0]
cursor.execute(ROOM_NUMBER_OF_DAYS, (room_id,))
days = cursor.fetchone()[0]
return {"name": name, "average": round(average, 2), "days": days}
def get_room_term(room_id, term):
terms = {"week": 7, "month": 30}
with connection:
with connection.cursor() as cursor:
cursor.execute(ROOM_NAME, (room_id,))
name = cursor.fetchone()[0]
cursor.execute(ROOM_TERM, (room_id, terms[term]))
dates_temperatures = cursor.fetchall()
average = sum(day[1] for day in dates_temperatures) / len(dates_temperatures)
return {
"name": name,
"temperatures": dates_temperatures,
"average": round(average, 2),
}
# Get the average temperature across all rooms, since their creation
@app.get("/api/average")
def get_global_avg():
with connection:
with connection.cursor() as cursor:
cursor.execute(GLOBAL_AVG)
average = cursor.fetchone()[0]
cursor.execute(GLOBAL_NUMBER_OF_DAYS)
days = cursor.fetchone()[0]
return {"average": round(average, 2), "days": days}