-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathapp.py
110 lines (82 loc) · 3.3 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
import json
from typing import Dict
import falcon
from pydantic import ValidationError
from models import Plant, User, UserPlant
from persistence import DoesNotExist, Repository
class PlantCollection:
def __init__(self, repo: Repository):
self.repo = repo
def on_get(self, req: falcon.Request, resp: falcon.Response):
resp.text = json.dumps({"plants": [p.dict() for p in self.repo.list()]})
def on_post(self, req: falcon.Request, resp: falcon.Response):
data = json.load(req.bounded_stream)
plant = Plant(**data)
self.repo.save(plant)
resp.text = json.dumps({"plant": plant.dict()})
class PlantResource:
def __init__(self, repo: Repository):
self.repo = repo
def on_get(self, _, resp: falcon.Response, plant_id: str):
repo = Repository.for_model(Plant)
try:
plant = repo.get(uid=plant_id)
resp.text = json.dumps(plant.dict())
except DoesNotExist as e:
raise falcon.HTTPNotFound() from e
class UserResource:
def __init__(self, repo: Repository):
self.repo = repo
def on_get(self, _, resp: falcon.Response, user_id: str):
user = self.repo.get(uid=user_id)
resp.text = json.dumps({"user": user.dict()})
class UserCollection:
def __init__(self, repo: Repository):
self.repo = repo
def on_post(self, req, resp):
data = json.load(req.bounded_stream)
user = User(**data)
self.repo.save(user)
resp.text = json.dumps({"user": user.dict()})
class UserPlantCollection:
def __init__(
self, plant_repo: Repository, user_repo: Repository, userplant_repo: Repository
):
self.plant_repo = plant_repo
self.user_repo = user_repo
self.userplant_repo = userplant_repo
def on_get(self, req: falcon.Request, resp: falcon.Response, user_id: str):
print(f"{user_id=}")
userplants = self.userplant_repo.filter("user_id", user_id)
resp.text = json.dumps({"userplants": [p.dict() for p in userplants]})
def on_post(self, req: falcon.Request, resp: falcon.Response, user_id: str):
# check user_id is valid
user = self.user_repo.get(uid=user_id)
data = json.load(req.bounded_stream)
data["user_id"] = user_id
userplant = UserPlant(**data)
# check plant ID is valid
self.plant_repo.get(uid=userplant.plant_id)
self.userplant_repo.save(userplant)
resp.text = json.dumps({"userplant": userplant.dict()})
def handle_validation_error(
req: falcon.Request, resp: falcon.Response, ex: ValidationError, params: Dict[str, str]
):
resp.status = falcon.HTTP_400
resp.text = ex.json()
def create_app(
user_repo: Repository, plant_repo: Repository, userplant_repo: Repository
):
app = falcon.App()
app.add_route("/plants", PlantCollection(plant_repo)),
app.add_route("/plants/{plant_id}", PlantResource(plant_repo))
app.add_route("/users", UserCollection(user_repo))
app.add_route("/users/{user_id}", UserResource(user_repo))
app.add_route(
"/users/{user_id}/plants",
UserPlantCollection(
plant_repo=plant_repo, user_repo=user_repo, userplant_repo=userplant_repo
),
)
app.add_error_handler(ValidationError, handle_validation_error)
return app