aioamazondevices 9.0.2__py3-none-any.whl → 11.0.3__py3-none-any.whl

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
aioamazondevices/login.py CHANGED
@@ -10,26 +10,26 @@ from http import HTTPMethod, HTTPStatus
10
10
  from typing import Any, cast
11
11
  from urllib.parse import parse_qs, urlencode
12
12
 
13
- import orjson
14
13
  from bs4 import BeautifulSoup, Tag
15
14
  from multidict import MultiDictProxy
16
15
  from yarl import URL
17
16
 
18
17
  from .const.http import (
19
- AMAZON_APP_BUNDLE_ID,
20
18
  AMAZON_APP_NAME,
21
19
  AMAZON_APP_VERSION,
22
20
  AMAZON_CLIENT_OS,
23
21
  AMAZON_DEVICE_SOFTWARE_VERSION,
24
22
  AMAZON_DEVICE_TYPE,
25
23
  DEFAULT_SITE,
26
- REFRESH_ACCESS_TOKEN,
27
24
  REFRESH_AUTH_COOKIES,
25
+ URI_DEVICES,
28
26
  URI_SIGNIN,
29
27
  )
28
+ from .const.metadata import MAX_CUSTOMER_ACCOUNT_RETRIES
30
29
  from .exceptions import (
31
30
  CannotAuthenticate,
32
31
  CannotRegisterDevice,
32
+ CannotRetrieveData,
33
33
  WrongMethod,
34
34
  )
35
35
  from .http_wrapper import AmazonHttpWrapper, AmazonSessionStateData
@@ -257,18 +257,16 @@ class AmazonLogin:
257
257
  device_login_data = await self._login_mode_interactive_oauth(otp_code)
258
258
 
259
259
  login_data = await self._register_device(device_login_data)
260
- self._session_state_data.load_login_stored_data(login_data)
260
+ self._session_state_data.login_stored_data = login_data
261
261
 
262
262
  await self._domain_refresh_auth_cookies()
263
263
 
264
+ await self.obtain_account_customer_id()
265
+
264
266
  self._session_state_data.login_stored_data.update(
265
267
  {"site": f"https://www.amazon.{self._session_state_data.domain}"}
266
268
  )
267
269
 
268
- # Can take a little while to register device but we need it
269
- # to be able to pickout account customer ID
270
- await asyncio.sleep(2)
271
-
272
270
  return self._session_state_data.login_stored_data
273
271
 
274
272
  async def _login_mode_interactive_oauth(
@@ -340,6 +338,8 @@ class AmazonLogin:
340
338
  obfuscate_email(self._session_state_data.login_email),
341
339
  )
342
340
 
341
+ await self.obtain_account_customer_id()
342
+
343
343
  return self._session_state_data.login_stored_data
344
344
 
345
345
  async def _get_alexa_domain(self) -> str:
@@ -359,7 +359,7 @@ class AmazonLogin:
359
359
 
360
360
  async def _refresh_auth_cookies(self) -> None:
361
361
  """Refresh cookies after domain swap."""
362
- _, json_token_resp = await self._refresh_data(REFRESH_AUTH_COOKIES)
362
+ _, json_token_resp = await self._http_wrapper.refresh_data(REFRESH_AUTH_COOKIES)
363
363
 
364
364
  # Need to take cookies from response and create them as cookies
365
365
  website_cookies = self._session_state_data.login_stored_data[
@@ -391,55 +391,49 @@ class AmazonLogin:
391
391
  await self._http_wrapper.clear_csrf_cookie()
392
392
  await self._refresh_auth_cookies()
393
393
 
394
- async def _refresh_data(self, data_type: str) -> tuple[bool, dict]:
395
- """Refresh data."""
396
- if not self._session_state_data.login_stored_data:
397
- _LOGGER.debug("No login data available, cannot refresh")
398
- return False, {}
399
-
400
- data = {
401
- "app_name": AMAZON_APP_NAME,
402
- "app_version": AMAZON_APP_VERSION,
403
- "di.sdk.version": "6.12.4",
404
- "source_token": self._session_state_data.login_stored_data["refresh_token"],
405
- "package_name": AMAZON_APP_BUNDLE_ID,
406
- "di.hw.version": "iPhone",
407
- "platform": "iOS",
408
- "requested_token_type": data_type,
409
- "source_token_type": "refresh_token",
410
- "di.os.name": "iOS",
411
- "di.os.version": AMAZON_CLIENT_OS,
412
- "current_version": "6.12.4",
413
- "previous_version": "6.12.4",
414
- "domain": f"www.amazon.{self._session_state_data.domain}",
415
- }
416
-
417
- _, raw_resp = await self._http_wrapper.session_request(
418
- method=HTTPMethod.POST,
419
- url="https://api.amazon.com/auth/token",
420
- input_data=data,
421
- json_data=False,
422
- )
423
- _LOGGER.debug(
424
- "Refresh data response %s with payload %s",
425
- raw_resp.status,
426
- orjson.dumps(data),
427
- )
428
-
429
- if raw_resp.status != HTTPStatus.OK:
430
- _LOGGER.debug("Failed to refresh data")
431
- return False, {}
432
-
433
- json_response = await self._http_wrapper.response_to_json(raw_resp, data_type)
394
+ async def obtain_account_customer_id(self) -> None:
395
+ """Find account customer id."""
396
+ for retry_count in range(MAX_CUSTOMER_ACCOUNT_RETRIES):
397
+ if not self._session_state_data.account_customer_id:
398
+ await asyncio.sleep(2) # allow time for device to be registered
434
399
 
435
- if data_type == REFRESH_ACCESS_TOKEN and (
436
- new_token := json_response.get(REFRESH_ACCESS_TOKEN)
437
- ):
438
- self._session_state_data.login_stored_data[REFRESH_ACCESS_TOKEN] = new_token
439
- return True, json_response
440
-
441
- if data_type == REFRESH_AUTH_COOKIES:
442
- return True, json_response
400
+ _LOGGER.debug(
401
+ "Lookup customer account ID (attempt %d/%d)",
402
+ retry_count + 1,
403
+ MAX_CUSTOMER_ACCOUNT_RETRIES,
404
+ )
405
+ _, raw_resp = await self._http_wrapper.session_request(
406
+ method=HTTPMethod.GET,
407
+ url=f"https://alexa.amazon.{self._session_state_data.domain}{URI_DEVICES}",
408
+ )
443
409
 
444
- _LOGGER.debug("Unexpected refresh data response")
445
- return False, {}
410
+ json_data = await self._http_wrapper.response_to_json(raw_resp, "devices")
411
+
412
+ for device in json_data.get("devices", []):
413
+ dev_serial = device.get("serialNumber")
414
+ if not dev_serial:
415
+ _LOGGER.warning(
416
+ "Skipping device without serial number: %s",
417
+ device["accountName"],
418
+ )
419
+ continue
420
+ if device["deviceType"] != AMAZON_DEVICE_TYPE:
421
+ continue
422
+
423
+ this_device_serial = self._session_state_data.login_stored_data[
424
+ "device_info"
425
+ ]["device_serial_number"]
426
+
427
+ for subdevice in device["appDeviceList"]:
428
+ if subdevice["serialNumber"] == this_device_serial:
429
+ account_owner_customer_id = device["deviceOwnerCustomerId"]
430
+ _LOGGER.debug(
431
+ "Setting account owner: %s",
432
+ account_owner_customer_id,
433
+ )
434
+ self._session_state_data.account_customer_id = (
435
+ account_owner_customer_id
436
+ )
437
+ return
438
+ if not self._session_state_data.account_customer_id:
439
+ raise CannotRetrieveData("Cannot find account owner customer ID")
@@ -37,7 +37,7 @@ class AmazonDevice:
37
37
  device_type: str
38
38
  device_owner_customer_id: str
39
39
  household_device: bool
40
- device_cluster_members: list[str]
40
+ device_cluster_members: dict[str, str | None]
41
41
  online: bool
42
42
  serial_number: str
43
43
  software_version: str
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: aioamazondevices
3
- Version: 9.0.2
3
+ Version: 11.0.3
4
4
  Summary: Python library to control Amazon devices
5
5
  License-Expression: Apache-2.0
6
6
  License-File: LICENSE
@@ -0,0 +1,23 @@
1
+ aioamazondevices/__init__.py,sha256=Q_uFYFnNYMzrZjtqxHRSTatCd-pn44lYmk0nn0Q3rOY,277
2
+ aioamazondevices/api.py,sha256=CQ_CQMhpwHryTX8Utqmw8AVKvi56UmD3xpozIXTe0Uc,19888
3
+ aioamazondevices/const/__init__.py,sha256=xQt8Smq2Ojjo30KKdev_gxDkcpY9PJlArTUXKel8oqs,38
4
+ aioamazondevices/const/devices.py,sha256=-W4yBSeACIsG3z_8MC_jrQoFJN1NZMe4c62XPee6q1k,11285
5
+ aioamazondevices/const/http.py,sha256=tgsRJWfx_SFRBk6T7TiClP02qIsPN4wShfMqRbZcQio,1204
6
+ aioamazondevices/const/metadata.py,sha256=zfia4dzEJQ1NPKiVzL-BslOngBRPSpL_vX0DPvIBhSg,1250
7
+ aioamazondevices/const/queries.py,sha256=weCYmUJedNyx1P8z_tG_6cHGMjICUVo6KOckkl4P_-w,1900
8
+ aioamazondevices/const/schedules.py,sha256=GohhoXSGxXEq_fEycSBsjaDJdIxuMtvspLVqaCmJjOU,1378
9
+ aioamazondevices/const/sounds.py,sha256=hdrXYKEuSOCw7fDdylvqLcDqD5poHzhgXEnUwq_TwDE,1923
10
+ aioamazondevices/exceptions.py,sha256=gRYrxNAJnrV6uRuMx5e76VMvtNKyceXd09q84pDBBrI,638
11
+ aioamazondevices/http_wrapper.py,sha256=MrPiWisER2piJy02yiP5eAP6SDuq-i10lIp5DN_epYc,14467
12
+ aioamazondevices/implementation/__init__.py,sha256=HU18CNdQaDYFksyHi8BL0a0FK0_knqo60ueOxH3zvgo,47
13
+ aioamazondevices/implementation/dnd.py,sha256=UrYSavcaddpYY7JA3aGXEjw7TCNaVERnEcunNcvheac,2065
14
+ aioamazondevices/implementation/notification.py,sha256=b9pvajZvdn-ykISuYFb9-BW4bVczUQGnnnuctJ9_kZY,8674
15
+ aioamazondevices/implementation/sequence.py,sha256=xDOzQouGrsPAAPjBfHkDIAuC0fTEB5uqi8QR4VmNHYs,5650
16
+ aioamazondevices/login.py,sha256=NNbZjaSC32uOGsKNkSx-URA4DIEGpCZSLp2Ey5xFv9U,17375
17
+ aioamazondevices/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
18
+ aioamazondevices/structures.py,sha256=2duKj9kiknFQHVGOysh0pWTQagTT-IDStCskayrwYSE,1425
19
+ aioamazondevices/utils.py,sha256=V6b5_CNJ5LtVBl9KSitr14nNle4mNDkZVojGhKfy60A,2373
20
+ aioamazondevices-11.0.3.dist-info/METADATA,sha256=BxEuuS0OxVpBisq1ViK3xhejCOdQBAwu_1b7glFrQSg,8308
21
+ aioamazondevices-11.0.3.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
22
+ aioamazondevices-11.0.3.dist-info/licenses/LICENSE,sha256=sS48k5sp9bFV-NSHDfAJuTZZ_-AP9ZDqUzQ9sffGlsg,11346
23
+ aioamazondevices-11.0.3.dist-info/RECORD,,
@@ -1,19 +0,0 @@
1
- aioamazondevices/__init__.py,sha256=-N24hqmuP5X5yZml6w5ASarPp5QOcX9uWEHMHmbHpVY,276
2
- aioamazondevices/api.py,sha256=Jwl6yx6gLjfPto6TNuP_e9rkl6qskzRPzDuGmV0kOAc,32729
3
- aioamazondevices/const/__init__.py,sha256=xQt8Smq2Ojjo30KKdev_gxDkcpY9PJlArTUXKel8oqs,38
4
- aioamazondevices/const/devices.py,sha256=yy4bKdvsy4HUIMVlCe-1SJboZqH060nyhcf_ZuES23Y,11056
5
- aioamazondevices/const/http.py,sha256=PMgfVl1K2vr_W3jkbD719x03aYte5mTObcPhRBayh7U,1151
6
- aioamazondevices/const/metadata.py,sha256=KbH184fSBZ5AvZAjas92qiAEwiSwWz4xSssznWhOWbI,1066
7
- aioamazondevices/const/queries.py,sha256=weCYmUJedNyx1P8z_tG_6cHGMjICUVo6KOckkl4P_-w,1900
8
- aioamazondevices/const/schedules.py,sha256=GohhoXSGxXEq_fEycSBsjaDJdIxuMtvspLVqaCmJjOU,1378
9
- aioamazondevices/const/sounds.py,sha256=hdrXYKEuSOCw7fDdylvqLcDqD5poHzhgXEnUwq_TwDE,1923
10
- aioamazondevices/exceptions.py,sha256=gRYrxNAJnrV6uRuMx5e76VMvtNKyceXd09q84pDBBrI,638
11
- aioamazondevices/http_wrapper.py,sha256=0gTjxXiqgK-lFSN5KW2PyxuQipp8JTfRPLYUsNnyp3E,11828
12
- aioamazondevices/login.py,sha256=Imkh78JsOiQEtTYXdU1yPC0CSh0nRGpxwLOQzCwfBiA,17247
13
- aioamazondevices/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
14
- aioamazondevices/structures.py,sha256=cGDUSsC9gNcA_rvAZhUwM5gCQ5U2nLl9HwMI4Mhnmyc,1413
15
- aioamazondevices/utils.py,sha256=V6b5_CNJ5LtVBl9KSitr14nNle4mNDkZVojGhKfy60A,2373
16
- aioamazondevices-9.0.2.dist-info/METADATA,sha256=pSXcilz1pm-goAp1GJvt5rLyDfXyT5qHLM00OmHmA00,8307
17
- aioamazondevices-9.0.2.dist-info/WHEEL,sha256=zp0Cn7JsFoX2ATtOhtaFYIiE2rmFAD4OcMhtUki8W3U,88
18
- aioamazondevices-9.0.2.dist-info/licenses/LICENSE,sha256=sS48k5sp9bFV-NSHDfAJuTZZ_-AP9ZDqUzQ9sffGlsg,11346
19
- aioamazondevices-9.0.2.dist-info/RECORD,,