aioamazondevices 1.3.0__tar.gz → 1.4.1__tar.gz

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.
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.3
2
2
  Name: aioamazondevices
3
- Version: 1.3.0
3
+ Version: 1.4.1
4
4
  Summary: Python library to control Amazon devices
5
5
  License: Apache-2.0
6
6
  Author: Simone Chemelli
@@ -15,13 +15,12 @@ Classifier: Programming Language :: Python :: 3
15
15
  Classifier: Programming Language :: Python :: 3.12
16
16
  Classifier: Programming Language :: Python :: 3.13
17
17
  Classifier: Topic :: Software Development :: Libraries
18
+ Requires-Dist: aiohttp
18
19
  Requires-Dist: babel
19
20
  Requires-Dist: beautifulsoup4
20
21
  Requires-Dist: colorlog
21
- Requires-Dist: httpx
22
22
  Requires-Dist: orjson
23
- Requires-Dist: pyasn1
24
- Requires-Dist: rsa
23
+ Requires-Dist: yarl
25
24
  Project-URL: Bug Tracker, https://github.com/chemelli74/aioamazondevices/issues
26
25
  Project-URL: Changelog, https://github.com/chemelli74/aioamazondevices/blob/main/CHANGELOG.md
27
26
  Project-URL: Repository, https://github.com/chemelli74/aioamazondevices
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "aioamazondevices"
3
- version = "1.3.0"
3
+ version = "1.4.1"
4
4
  description = "Python library to control Amazon devices"
5
5
  authors = ["Simone Chemelli <simone.chemelli@gmail.com>"]
6
6
  license = "Apache-2.0"
@@ -22,14 +22,13 @@ packages = [
22
22
  "Changelog" = "https://github.com/chemelli74/aioamazondevices/blob/main/CHANGELOG.md"
23
23
 
24
24
  [tool.poetry.dependencies]
25
+ aiohttp = "*"
25
26
  python = "^3.12"
26
27
  babel = "*"
27
28
  beautifulsoup4 = "*"
28
29
  colorlog = "*"
29
- httpx = "*"
30
30
  orjson = "*"
31
- pyasn1 = "*"
32
- rsa = "*"
31
+ yarl = "*"
33
32
 
34
33
  [tool.poetry.group.dev.dependencies]
35
34
  pytest = "^8.1"
@@ -1,6 +1,6 @@
1
1
  """aioamazondevices library."""
2
2
 
3
- __version__ = "1.3.0"
3
+ __version__ = "1.4.1"
4
4
 
5
5
 
6
6
  from .api import AmazonDevice, AmazonEchoApi
@@ -8,14 +8,16 @@ import uuid
8
8
  from dataclasses import dataclass
9
9
  from datetime import UTC, datetime, timedelta
10
10
  from http import HTTPStatus
11
+ from http.cookies import SimpleCookie
11
12
  from pathlib import Path
12
13
  from typing import Any, cast
13
14
  from urllib.parse import parse_qs, urlencode
14
15
 
15
16
  import orjson
17
+ from aiohttp import ClientResponse, ClientSession
16
18
  from babel import Locale
17
19
  from bs4 import BeautifulSoup, Tag
18
- from httpx import URL, AsyncClient, Response
20
+ from yarl import URL
19
21
 
20
22
  from .const import (
21
23
  _LOGGER,
@@ -95,14 +97,14 @@ class AmazonEchoApi:
95
97
  self._login_stored_data = login_data
96
98
  self._serial = self._serial_number()
97
99
 
98
- self.session: AsyncClient
100
+ self.session: ClientSession
99
101
 
100
- def _load_website_cookies(self) -> dict[str, Any]:
102
+ def _load_website_cookies(self) -> list[SimpleCookie]:
101
103
  """Get website cookies, if avaliables."""
102
104
  if not self._login_stored_data:
103
- return {}
105
+ return []
104
106
 
105
- return cast("dict", self._login_stored_data["website_cookies"])
107
+ return cast("list", self._login_stored_data["website_cookies"])
106
108
 
107
109
  def _serial_number(self) -> str:
108
110
  """Get or calculate device serial number."""
@@ -213,13 +215,11 @@ class AmazonEchoApi:
213
215
 
214
216
  def _client_session(self) -> None:
215
217
  """Create HTTP client session."""
216
- if not hasattr(self, "session") or self.session.is_closed:
217
- _LOGGER.debug("Creating HTTP session (httpx)")
218
- self.session = AsyncClient(
219
- base_url=f"https://www.amazon.{self._domain}",
218
+ if not hasattr(self, "session") or self.session.closed:
219
+ _LOGGER.debug("Creating HTTP session (aiohttp)")
220
+ self.session = ClientSession(
220
221
  headers=DEFAULT_HEADERS,
221
222
  cookies=self._cookies,
222
- follow_redirects=True,
223
223
  )
224
224
 
225
225
  async def _session_request(
@@ -228,7 +228,7 @@ class AmazonEchoApi:
228
228
  url: str,
229
229
  input_data: dict[str, Any] | None = None,
230
230
  json_data: bool = False,
231
- ) -> tuple[BeautifulSoup, Response]:
231
+ ) -> tuple[BeautifulSoup, ClientResponse]:
232
232
  """Return request response context data."""
233
233
  _LOGGER.debug(
234
234
  "%s request: %s with payload %s [json=%s]",
@@ -255,22 +255,23 @@ class AmazonEchoApi:
255
255
  data=input_data if not json_data else orjson.dumps(input_data),
256
256
  cookies=self._load_website_cookies(),
257
257
  headers=headers,
258
+ allow_redirects=True,
258
259
  )
259
260
  content_type: str = resp.headers.get("Content-Type", "")
260
261
  _LOGGER.debug(
261
262
  "Response %s for url %s with content type: %s",
262
- resp.status_code,
263
+ resp.status,
263
264
  url,
264
265
  content_type,
265
266
  )
266
267
 
267
268
  await self._save_to_file(
268
- resp.text,
269
+ await resp.text(),
269
270
  url,
270
271
  mimetypes.guess_extension(content_type.split(";")[0]) or ".raw",
271
272
  )
272
273
 
273
- return BeautifulSoup(resp.content, "html.parser"), resp
274
+ return BeautifulSoup(await resp.read(), "html.parser"), resp
274
275
 
275
276
  async def _save_to_file(
276
277
  self,
@@ -311,7 +312,7 @@ class AmazonEchoApi:
311
312
 
312
313
  _LOGGER.warning("Saving data to %s", fullpath)
313
314
 
314
- with Path.open(fullpath, "w+") as file:
315
+ with Path.open(fullpath, mode="w", encoding="utf-8") as file:
315
316
  file.write(data)
316
317
  file.write("\n")
317
318
 
@@ -364,7 +365,7 @@ class AmazonEchoApi:
364
365
  )
365
366
  resp_json = resp.json()
366
367
 
367
- if resp.status_code != HTTPStatus.OK:
368
+ if resp.status != HTTPStatus.OK:
368
369
  _LOGGER.error(
369
370
  "Cannot register device for %s: %s",
370
371
  self._login_email,
@@ -499,8 +500,8 @@ class AmazonEchoApi:
499
500
  async def close(self) -> None:
500
501
  """Close http client session."""
501
502
  if hasattr(self, "session"):
502
- _LOGGER.debug("Closing HTTP session (httpx)")
503
- await self.session.aclose()
503
+ _LOGGER.debug("Closing HTTP session (aiohttp)")
504
+ await self.session.close()
504
505
 
505
506
  async def get_devices_data(
506
507
  self,
@@ -513,16 +514,16 @@ class AmazonEchoApi:
513
514
  url=f"https://alexa.amazon.{self._domain}{URI_QUERIES[key]}",
514
515
  )
515
516
  _LOGGER.debug("Response URL: %s", raw_resp.url)
516
- response_code = raw_resp.status_code
517
+ response_code = raw_resp.status
517
518
  _LOGGER.debug("Response code: |%s|", response_code)
518
519
 
519
- response_data = raw_resp.text
520
+ response_data = await raw_resp.text()
520
521
  _LOGGER.debug("Response data: |%s|", response_data)
521
522
 
522
523
  if not self._csrf_cookie:
523
- self._csrf_cookie = raw_resp.cookies.get(CSRF_COOKIE)
524
+ self._csrf_cookie = raw_resp.cookies.get(CSRF_COOKIE).value
524
525
 
525
- json_data = {} if len(response_data) == 0 else raw_resp.json()
526
+ json_data = {} if len(response_data) == 0 else await raw_resp.json()
526
527
 
527
528
  _LOGGER.debug("JSON data: |%s|", json_data)
528
529
 
@@ -566,14 +567,14 @@ class AmazonEchoApi:
566
567
  method="GET",
567
568
  url=f"https://alexa.amazon.{self._domain}/api/bootstrap?version=0",
568
569
  )
569
- if raw_resp.status_code != HTTPStatus.OK:
570
+ if raw_resp.status != HTTPStatus.OK:
570
571
  _LOGGER.debug(
571
572
  "Session not authenticated: reply error %s",
572
- raw_resp.status_code,
573
+ raw_resp.status,
573
574
  )
574
575
  return False
575
576
 
576
- resp_json = raw_resp.json()
577
+ resp_json = await raw_resp.json()
577
578
  if not (authentication := resp_json.get("authentication")):
578
579
  _LOGGER.debug('Session not authenticated: reply missing "authentication"')
579
580
  return False
@@ -74,4 +74,6 @@ DEVICE_TYPE_TO_MODEL = {
74
74
  "A3S5BH2HU6VAYF": "Echo Dot (Gen2)",
75
75
  "A4ZXE0RM7LQ7A": "Echo Dot (Gen5)",
76
76
  "AKNO1N0KSFN8L": "Echo Dot (Gen1)",
77
+ "A3C9PE6TNYLTCH": "Speaker Group",
78
+ "A1Q6UGEXJZWJQ0": "Fire TV Stick 4K",
77
79
  }