forked from Lash-L/python-snoo
-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathbaby.py
More file actions
116 lines (93 loc) · 4.42 KB
/
baby.py
File metadata and controls
116 lines (93 loc) · 4.42 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
from datetime import datetime
from .containers import Activity, BabyData, BreastfeedingActivity, DiaperActivity, DiaperTypes
from .exceptions import SnooBabyError
from .snoo import Snoo
class Baby:
def __init__(self, baby_id: str, snoo: Snoo):
self.baby_id = baby_id
self.snoo = snoo
self.baby_url = f"https://api-us-east-1-prod.happiestbaby.com/us/me/v10/babies/{self.baby_id}"
self.activity_base_url = "https://api-us-east-1-prod.happiestbaby.com/cs/me/v11"
@property
def session(self):
return self.snoo.session
async def get_status(self) -> BabyData:
hdrs = self.snoo.generate_snoo_auth_headers(self.snoo.tokens.aws_id)
try:
r = await self.session.get(self.baby_url, headers=hdrs)
resp = await r.json()
except Exception as ex:
raise SnooBabyError from ex
return BabyData.from_dict(resp)
async def get_activity_data(self, from_date: datetime, to_date: datetime) -> list[Activity]:
"""Get activity data for this baby including feeding and diaper changes
Args:
from_date: Start date for activity range
to_date: End date for activity range
Returns:
List of typed Activity objects (DiaperActivity or BreastfeedingActivity)
"""
hdrs = self.snoo.generate_snoo_auth_headers(self.snoo.tokens.aws_id)
url = f"{self.activity_base_url}/babies/{self.baby_id}/journals/grouped-tracking"
params = {
"group": "activity",
"fromDateTime": from_date.astimezone().isoformat(timespec="milliseconds"),
"toDateTime": to_date.astimezone().isoformat(timespec="milliseconds"),
}
try:
r = await self.session.get(url, headers=hdrs, params=params)
resp = await r.json()
if r.status < 200 or r.status >= 300:
raise SnooBabyError(f"Failed to get activity data: {r.status}: {resp}. Payload: {params}")
activities: list[Activity] = []
if isinstance(resp, list):
for activity in resp:
activity_type = activity.get("type", "").lower()
if activity_type == "diaper":
activities.append(DiaperActivity.from_dict(activity))
elif activity_type == "breastfeeding":
activities.append(BreastfeedingActivity.from_dict(activity))
else:
# Other activity types exist but aren't supported yet
raise SnooBabyError(f"Unknown activity type: {activity_type}")
else:
raise SnooBabyError(f"Unexpected response format: {type(resp)}")
return activities
except Exception as ex:
raise SnooBabyError from ex
async def log_diaper_change(
self,
diaper_types: list[DiaperTypes],
note: str | None = None,
start_time: datetime | None = None,
) -> DiaperActivity:
"""Log a diaper change for this baby
Args:
diaper_types (list): List of diaper types. e.g. ['pee'], ['poo'], or ['pee', 'poo']
note (str, optional): Optional note about the diaper change
start_time (datetime, optional): Diaper change timestamp, doesn't allow length.
Defaults to current local time if not provided.
"""
if not start_time:
start_time = datetime.now()
# Always include the timezone indicator in the ISO string - seems to be required by the API
if start_time.tzinfo is None:
start_time = start_time.astimezone()
hdrs = self.snoo.generate_snoo_auth_headers(self.snoo.tokens.aws_id)
url = f"{self.activity_base_url}/journals"
payload = {
"babyId": self.baby_id,
"data": {"types": [dt.value for dt in diaper_types]},
"type": "diaper",
"startTime": start_time.isoformat(timespec="milliseconds"),
}
if note:
payload["note"] = note
try:
r = await self.session.post(url, headers=hdrs, json=payload)
resp = await r.json()
if r.status < 200 or r.status >= 300:
raise SnooBabyError(f"Failed to log diaper change: {r.status}: {resp}. Payload: {payload}")
return DiaperActivity.from_dict(resp)
except Exception as ex:
raise SnooBabyError from ex