|
@@ -1,6 +1,6 @@
|
1
|
|
-'''
|
|
1
|
+"""
|
2
|
2
|
Provides access to the models stored in the database, via the server.
|
3
|
|
-'''
|
|
3
|
+"""
|
4
|
4
|
from typing import NamedTuple
|
5
|
5
|
from urllib.parse import urljoin
|
6
|
6
|
|
|
@@ -8,45 +8,49 @@ import requests
|
8
|
8
|
|
9
|
9
|
from . import logger
|
10
|
10
|
|
11
|
|
-LOG = logger.getLogger('model')
|
|
11
|
+LOG = logger.getLogger("model")
|
12
|
12
|
|
13
|
13
|
SERVER_URL = "http://127.0.0.1:5000"
|
14
|
14
|
|
|
15
|
+
|
15
|
16
|
class Person(NamedTuple):
|
16
|
|
- ''' Represents a Person, as retrieved from the database. '''
|
|
17
|
+ """ Represents a Person, as retrieved from the database. """
|
|
18
|
+
|
17
|
19
|
name: str
|
18
|
20
|
person_id: int = None
|
19
|
21
|
consumptions: dict = {}
|
20
|
22
|
|
21
|
23
|
def add_consumption(self, type_id: str) -> bool:
|
22
|
|
- ''' Register a consumption for this Person. '''
|
|
24
|
+ """ Register a consumption for this Person. """
|
23
|
25
|
req = requests.post(
|
24
|
|
- urljoin(SERVER_URL,
|
25
|
|
- f'people/{self.person_id}/add_consumption/{type_id}')
|
|
26
|
+ urljoin(SERVER_URL, f"people/{self.person_id}/add_consumption/{type_id}")
|
26
|
27
|
)
|
27
|
28
|
try:
|
28
|
29
|
data = req.json()
|
29
|
30
|
|
30
|
|
- if 'error' in data:
|
|
31
|
+ if "error" in data:
|
31
|
32
|
LOG.error(
|
32
|
|
- 'Could not add consumption for %s (%s): %s',
|
33
|
|
- self.person_id, req.status_code, data
|
|
33
|
+ "Could not add consumption for %s (%s): %s",
|
|
34
|
+ self.person_id,
|
|
35
|
+ req.status_code,
|
|
36
|
+ data,
|
34
|
37
|
)
|
35
|
38
|
return False
|
36
|
39
|
|
37
|
|
- self.consumptions.update(data['person']['consumptions'])
|
|
40
|
+ self.consumptions.update(data["person"]["consumptions"])
|
38
|
41
|
|
39
|
42
|
return True
|
40
|
43
|
except ValueError:
|
41
|
44
|
LOG.error(
|
42
|
|
- 'Did not get JSON on adding Consumption (%s): %s',
|
43
|
|
- req.status_code, req.content
|
|
45
|
+ "Did not get JSON on adding Consumption (%s): %s",
|
|
46
|
+ req.status_code,
|
|
47
|
+ req.content,
|
44
|
48
|
)
|
45
|
49
|
return False
|
46
|
50
|
|
47
|
|
- def create(self) -> 'Person':
|
48
|
|
- ''' Create a new Person from the current attributes. As tuples are
|
49
|
|
- immutable, a new Person with the correct id is returned. '''
|
|
51
|
+ def create(self) -> "Person":
|
|
52
|
+ """ Create a new Person from the current attributes. As tuples are
|
|
53
|
+ immutable, a new Person with the correct id is returned. """
|
50
|
54
|
req = requests.post(
|
51
|
55
|
urljoin(SERVER_URL, "people"), json={"person": {"name": self.name}}
|
52
|
56
|
)
|
|
@@ -55,163 +59,164 @@ class Person(NamedTuple):
|
55
|
59
|
data = req.json()
|
56
|
60
|
except ValueError:
|
57
|
61
|
LOG.error(
|
58
|
|
- 'Did not get JSON on adding Person (%s): %s',
|
59
|
|
- req.status_code, req.content
|
|
62
|
+ "Did not get JSON on adding Person (%s): %s",
|
|
63
|
+ req.status_code,
|
|
64
|
+ req.content,
|
60
|
65
|
)
|
61
|
66
|
return None
|
62
|
67
|
|
63
|
|
- if 'error' in data or req.status_code != 201:
|
64
|
|
- LOG.error(
|
65
|
|
- 'Could not create Person (%s): %s',
|
66
|
|
- req.status_code, data
|
67
|
|
- )
|
|
68
|
+ if "error" in data or req.status_code != 201:
|
|
69
|
+ LOG.error("Could not create Person (%s): %s", req.status_code, data)
|
68
|
70
|
return None
|
69
|
71
|
|
70
|
|
- return Person.from_dict(data['person'])
|
|
72
|
+ return Person.from_dict(data["person"])
|
71
|
73
|
|
72
|
74
|
@classmethod
|
73
|
|
- def get(cls, person_id: int) -> 'Person':
|
74
|
|
- ''' Retrieve a Person by id. '''
|
75
|
|
- req = requests.get(urljoin(SERVER_URL, f'/people/{person_id}'))
|
|
75
|
+ def get(cls, person_id: int) -> "Person":
|
|
76
|
+ """ Retrieve a Person by id. """
|
|
77
|
+ req = requests.get(urljoin(SERVER_URL, f"/people/{person_id}"))
|
76
|
78
|
|
77
|
79
|
try:
|
78
|
80
|
data = req.json()
|
79
|
81
|
|
80
|
|
- if 'error' in data:
|
|
82
|
+ if "error" in data:
|
81
|
83
|
LOG.warning(
|
82
|
|
- 'Could not get person %s (%s): %s',
|
83
|
|
- person_id, req.status_code, data
|
|
84
|
+ "Could not get person %s (%s): %s", person_id, req.status_code, data
|
84
|
85
|
)
|
85
|
86
|
return None
|
86
|
87
|
|
87
|
|
- return Person.from_dict(data['person'])
|
|
88
|
+ return Person.from_dict(data["person"])
|
88
|
89
|
|
89
|
90
|
except ValueError:
|
90
|
91
|
LOG.error(
|
91
|
|
- 'Did not get JSON from server on getting Person (%s): %s',
|
92
|
|
- req.status_code, req.content
|
|
92
|
+ "Did not get JSON from server on getting Person (%s): %s",
|
|
93
|
+ req.status_code,
|
|
94
|
+ req.content,
|
93
|
95
|
)
|
94
|
96
|
return None
|
95
|
97
|
|
96
|
98
|
@classmethod
|
97
|
|
- def get_all(cls) -> ['Person']:
|
98
|
|
- ''' Get all active People. '''
|
99
|
|
- req = requests.get(urljoin(SERVER_URL, '/people'))
|
|
99
|
+ def get_all(cls) -> ["Person"]:
|
|
100
|
+ """ Get all active People. """
|
|
101
|
+ req = requests.get(urljoin(SERVER_URL, "/people"))
|
100
|
102
|
|
101
|
103
|
try:
|
102
|
104
|
data = req.json()
|
103
|
105
|
|
104
|
|
- if 'error' in data:
|
105
|
|
- LOG.warning(
|
106
|
|
- 'Could not get people (%s): %s',
|
107
|
|
- req.status_code, data
|
108
|
|
- )
|
|
106
|
+ if "error" in data:
|
|
107
|
+ LOG.warning("Could not get people (%s): %s", req.status_code, data)
|
109
|
108
|
|
110
|
|
- return [Person.from_dict(item) for item in data['people']]
|
|
109
|
+ return [Person.from_dict(item) for item in data["people"]]
|
111
|
110
|
|
112
|
111
|
except ValueError:
|
113
|
112
|
LOG.error(
|
114
|
|
- 'Did not get JSON from server on getting People (%s): %s',
|
115
|
|
- req.status_code, req.content
|
|
113
|
+ "Did not get JSON from server on getting People (%s): %s",
|
|
114
|
+ req.status_code,
|
|
115
|
+ req.content,
|
116
|
116
|
)
|
117
|
117
|
return None
|
118
|
118
|
|
119
|
119
|
@classmethod
|
120
|
|
- def from_dict(cls, data: dict) -> 'Person':
|
121
|
|
- ''' Reconstruct a Person object from a dict. '''
|
|
120
|
+ def from_dict(cls, data: dict) -> "Person":
|
|
121
|
+ """ Reconstruct a Person object from a dict. """
|
122
|
122
|
return Person(
|
123
|
|
- name = data['name'],
|
124
|
|
- person_id = data['person_id'],
|
125
|
|
- consumptions = data['consumptions']
|
|
123
|
+ name=data["name"],
|
|
124
|
+ person_id=data["person_id"],
|
|
125
|
+ consumptions=data["consumptions"],
|
126
|
126
|
)
|
127
|
127
|
|
|
128
|
+
|
128
|
129
|
class ConsumptionType(NamedTuple):
|
129
|
|
- ''' Represents a stored ConsumptionType. '''
|
|
130
|
+ """ Represents a stored ConsumptionType. """
|
130
|
131
|
|
131
|
132
|
name: str
|
132
|
133
|
consumption_type_id: int = None
|
133
|
134
|
icon: str = None
|
134
|
135
|
|
135
|
|
- def create(self) -> 'Person':
|
136
|
|
- ''' Create a new ConsumptionType from the current attributes. As tuples
|
|
136
|
+ def create(self) -> "Person":
|
|
137
|
+ """ Create a new ConsumptionType from the current attributes. As tuples
|
137
|
138
|
are immutable, a new ConsumptionType with the correct id is returned.
|
138
|
|
- '''
|
|
139
|
+ """
|
139
|
140
|
req = requests.post(
|
140
|
|
- urljoin(SERVER_URL, "consumption_types"), json={"consumption_type":
|
141
|
|
- {"name": self.name, "icon": self.icon}}
|
|
141
|
+ urljoin(SERVER_URL, "consumption_types"),
|
|
142
|
+ json={"consumption_type": {"name": self.name, "icon": self.icon}},
|
142
|
143
|
)
|
143
|
144
|
|
144
|
145
|
try:
|
145
|
146
|
data = req.json()
|
146
|
147
|
except ValueError:
|
147
|
148
|
LOG.error(
|
148
|
|
- 'Did not get JSON on adding ConsumptionType (%s): %s',
|
149
|
|
- req.status_code, req.content
|
|
149
|
+ "Did not get JSON on adding ConsumptionType (%s): %s",
|
|
150
|
+ req.status_code,
|
|
151
|
+ req.content,
|
150
|
152
|
)
|
151
|
153
|
return None
|
152
|
154
|
|
153
|
|
- if 'error' in data or req.status_code != 201:
|
|
155
|
+ if "error" in data or req.status_code != 201:
|
154
|
156
|
LOG.error(
|
155
|
|
- 'Could not create ConsumptionType (%s): %s',
|
156
|
|
- req.status_code, data
|
|
157
|
+ "Could not create ConsumptionType (%s): %s", req.status_code, data
|
157
|
158
|
)
|
158
|
159
|
return None
|
159
|
160
|
|
160
|
|
- return Person.from_dict(data['consumption_type'])
|
|
161
|
+ return Person.from_dict(data["consumption_type"])
|
161
|
162
|
|
162
|
163
|
@classmethod
|
163
|
|
- def get(cls, consumption_type_id: int) -> 'ConsumptionType':
|
164
|
|
- ''' Retrieve a ConsumptionType by id. '''
|
165
|
|
- req = requests.get(urljoin(SERVER_URL,
|
166
|
|
- f'/consumption_types/{consumption_type_id}'))
|
|
164
|
+ def get(cls, consumption_type_id: int) -> "ConsumptionType":
|
|
165
|
+ """ Retrieve a ConsumptionType by id. """
|
|
166
|
+ req = requests.get(
|
|
167
|
+ urljoin(SERVER_URL, f"/consumption_types/{consumption_type_id}")
|
|
168
|
+ )
|
167
|
169
|
|
168
|
170
|
try:
|
169
|
171
|
data = req.json()
|
170
|
172
|
|
171
|
|
- if 'error' in data:
|
|
173
|
+ if "error" in data:
|
172
|
174
|
LOG.warning(
|
173
|
|
- 'Could not get consumption type %s (%s): %s',
|
174
|
|
- consumption_type_id, req.status_code, data
|
|
175
|
+ "Could not get consumption type %s (%s): %s",
|
|
176
|
+ consumption_type_id,
|
|
177
|
+ req.status_code,
|
|
178
|
+ data,
|
175
|
179
|
)
|
176
|
180
|
return None
|
177
|
181
|
|
178
|
|
- return cls.from_dict(data['consumption_type'])
|
|
182
|
+ return cls.from_dict(data["consumption_type"])
|
179
|
183
|
|
180
|
184
|
except ValueError:
|
181
|
185
|
LOG.error(
|
182
|
|
- 'Did not get JSON from server on getting consumption type (%s): %s',
|
183
|
|
- req.status_code, req.content
|
|
186
|
+ "Did not get JSON from server on getting consumption type (%s): %s",
|
|
187
|
+ req.status_code,
|
|
188
|
+ req.content,
|
184
|
189
|
)
|
185
|
190
|
return None
|
186
|
191
|
|
187
|
192
|
@classmethod
|
188
|
|
- def get_all(cls) -> ['ConsumptionType']:
|
189
|
|
- ''' Get all active ConsumptionTypes. '''
|
190
|
|
- req = requests.get(urljoin(SERVER_URL, '/consumption_types'))
|
|
193
|
+ def get_all(cls) -> ["ConsumptionType"]:
|
|
194
|
+ """ Get all active ConsumptionTypes. """
|
|
195
|
+ req = requests.get(urljoin(SERVER_URL, "/consumption_types"))
|
191
|
196
|
|
192
|
197
|
try:
|
193
|
198
|
data = req.json()
|
194
|
199
|
|
195
|
|
- if 'error' in data:
|
|
200
|
+ if "error" in data:
|
196
|
201
|
LOG.warning(
|
197
|
|
- 'Could not get consumption types (%s): %s',
|
198
|
|
- req.status_code, data
|
|
202
|
+ "Could not get consumption types (%s): %s", req.status_code, data
|
199
|
203
|
)
|
200
|
204
|
|
201
|
|
- return [cls.from_dict(item) for item in data['consumption_types']]
|
|
205
|
+ return [cls.from_dict(item) for item in data["consumption_types"]]
|
202
|
206
|
|
203
|
207
|
except ValueError:
|
204
|
208
|
LOG.error(
|
205
|
|
- 'Did not get JSON from server on getting ConsumptionTypes (%s): %s',
|
206
|
|
- req.status_code, req.content
|
|
209
|
+ "Did not get JSON from server on getting ConsumptionTypes (%s): %s",
|
|
210
|
+ req.status_code,
|
|
211
|
+ req.content,
|
207
|
212
|
)
|
208
|
213
|
return None
|
209
|
214
|
|
210
|
215
|
@classmethod
|
211
|
|
- def from_dict(cls, data: dict) -> 'ConsumptionType':
|
212
|
|
- ''' Reconstruct a ConsumptionType from a dict. '''
|
|
216
|
+ def from_dict(cls, data: dict) -> "ConsumptionType":
|
|
217
|
+ """ Reconstruct a ConsumptionType from a dict. """
|
213
|
218
|
return ConsumptionType(
|
214
|
|
- name = data['name'],
|
215
|
|
- consumption_type_id = data['consumption_type_id'],
|
216
|
|
- icon = data.get('icon')
|
|
219
|
+ name=data["name"],
|
|
220
|
+ consumption_type_id=data["consumption_type_id"],
|
|
221
|
+ icon=data.get("icon"),
|
217
|
222
|
)
|