Repository navigation
Expand file tree
/
Copy pathfastapi_engine.py
More file actions
154 lines (111 loc) · 3.9 KB
/
Copy pathfastapi_engine.py
File metadata and controls
154 lines (111 loc) · 3.9 KB
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
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
import logging
from typing import List
from fastapi import FastAPI
from fastapi.responses import RedirectResponse
from pydantic import BaseModel
import common.mqtt_messages as mqtt_messages
import common.mqtt_connection as mqtt_connection
import common.mqtt_topics as mqtt_topics
import server.database as database
import server.storage as storage
app = FastAPI()
@app.get("/")
async def root():
response = RedirectResponse(url='/docs')
return response
@app.get("/view-available-recipes")
async def view_available_recipes():
"""
Returns the list of recipes available for the coffee machines
"""
recipes = [i for i in database.get_recipes().find()]
for i in recipes:
del i['_id']
return {"recipes": recipes}
@app.post("/add-new-recipe")
async def add_new_recipe(recipe: mqtt_messages.Recipe):
"""
Adds a new recipe to the database
"""
if database.get_recipes().count_documents({"drink_name": recipe.drink_name}) > 0:
return {
"status": "FAIL",
"error_message": "There is already a recipe with this name."
}
database.get_recipes().insert_one(recipe.to_dict())
return {"status": "OK"}
@app.post("/delete-recipe")
async def delete_recipe(recipe_name: str):
"""
Deletes the recipe from the DB assuming it exists
"""
# no recipe was found
if database.get_recipes().count_documents({"drink_name": recipe_name}) == 0:
return {"status": "FAIL", "error_message": "No recipe was found with that name"}
database.get_recipes().delete_many({"drink_name": recipe_name})
return {"status": "OK"}
@app.get("/view-order-history")
async def view_order_history():
"""
Get the list of orders made to any of the coffee machines
"""
orders = [i for i in database.get_orders().find()]
orders.sort(key=lambda order: -order["timestamp"])
for i in orders:
del i['_id']
return {"orders": orders}
@app.get("/view-popular-drinks")
async def view_popular_drinks():
"""
Get the popularity of all the drinks as a histogram
"""
orders = [i for i in database.get_orders().find({'success': 'Done'})]
for i in orders:
del i['_id']
# get the count of each coffee type
order_frequency = dict()
for order in orders:
if order['coffee_name'] in order_frequency:
order_frequency[order['coffee_name']] += 1
else:
order_frequency[order['coffee_name']] = 1
result = []
for order_name in order_frequency:
result.append((order_name, order_frequency[order_name]))
# sort in decreasing order by the count
result.sort(key = lambda x: -x[1])
return {"drinks": result}
class SingleMachineStatusAnswer(BaseModel):
machine_id: str
last_heartbeat: float
machine_levels: mqtt_messages.MachineLevels
class MachinesStatusAnswer(BaseModel):
"""
Answer to a machine status request.
"""
machines: List[SingleMachineStatusAnswer]
@app.get("/view-machines-status", response_model=MachinesStatusAnswer)
async def view_machines_status():
"""
Get the current status of each machine
"""
logging.info(f"We have {storage.coffee_machines_last_heartbeat}")
response = MachinesStatusAnswer(machines=[])
for machine_id in storage.coffee_machines_last_heartbeat:
machine = SingleMachineStatusAnswer(
machine_id=machine_id,
last_heartbeat=storage.coffee_machines_last_heartbeat[machine_id],
machine_levels=storage.coffee_machines_levels[machine_id]
)
response.machines.append(machine)
return response
@app.post("/request-new-drink")
async def order_drink_to_coffee_machine(request: mqtt_messages.CoffeeOrderRequest):
"""
Request a particular coffee machine to deliver a drink
"""
mqtt_connection.publish(
mqtt_topics.COFFEE_ORDER_TOPIC,
request
)
return {"status": "OK"}