suggested solution is https://docs.aiohttp.org/en/stable/client_quickstart.html#streaming-uploads
diff --git a/kasa/aestransport.py b/kasa/aestransport.py index 65b0045..ca74cc6 100644 --- a/kasa/aestransport.py +++ b/kasa/aestransport.py @@ -8,7 +8,7 @@ import base64 import hashlib import logging import time -from typing import Dict, Optional, cast +from typing import Dict, Optional, cast, TYPE_CHECKING from cryptography.hazmat.primitives import padding, serialization from cryptography.hazmat.primitives.asymmetric import padding as asymmetric_padding @@ -86,6 +86,8 @@ class AesTransport(BaseTransport): self._login_token = None + self._key_pair: Optional[KeyPair] = None + _LOGGER.debug("Created AES transport for %s", self._host) @property @@ -185,33 +187,35 @@ class AesTransport(BaseTransport): self._handle_response_error_code(resp_dict, "Error logging in") self._login_token = resp_dict["result"]["token"] + async def _generate_request_body(self) -> str: + """Generate the request body.""" + self._key_pair = KeyPair.create_key_pair() + pub_key = ( + "-----BEGIN PUBLIC KEY-----\n" + + self._key_pair.get_public_key() + + "\n-----END PUBLIC KEY-----\n" + ) + handshake_params = {"key": pub_key} + _LOGGER.debug(f"Handshake params: {handshake_params}") + request_body = {"method": "handshake", "params": handshake_params} + _LOGGER.debug(f"Request {request_body}") + return json_dumps(request_body) + async def perform_handshake(self): """Perform the handshake.""" _LOGGER.debug("Will perform handshaking...") _LOGGER.debug("Generating keypair") + self._key_pair = None self._handshake_done = False self._session_expire_at = None self._session_cookie = None url = f"http://{self._host}/app" - key_pair = KeyPair.create_key_pair() - - pub_key = ( - "-----BEGIN PUBLIC KEY-----\n" - + key_pair.get_public_key() - + "\n-----END PUBLIC KEY-----\n" - ) - handshake_params = {"key": pub_key} - _LOGGER.debug(f"Handshake params: {handshake_params}") - - request_body = {"method": "handshake", "params": handshake_params} - - _LOGGER.debug(f"Request {request_body}") status_code, resp_dict = await self._http_client.post( url, - json=request_body, + data=self._generate_request_body(), headers=self.COMMON_HEADERS, cookies_dict=self._session_cookie, ) @@ -240,8 +244,10 @@ class AesTransport(BaseTransport): self._session_cookie = {self.SESSION_COOKIE_NAME: cookie} self._session_expire_at = time.time() + 86400 + if TYPE_CHECKING: + assert self._key_pair is not None self._encryption_session = AesEncyptionSession.create_from_keypair( - handshake_key, key_pair + handshake_key, self._key_pair ) self._handshake_done = True
PR created #687.
aiohttp needs an async_generator rather than a coroutine but this works.
Prepare 0.6.1
Prepare 0.6.1 (#709)
Prepare 0.6.1 (python-kasa#709)
Activity
sdb9696 commented on Jan 23, 2024
PR created #687.
aiohttp needs an async_generator rather than a coroutine but this works.
Prepare 0.6.1
Prepare 0.6.1 (#709)
Prepare 0.6.1 (python-kasa#709)