mirror of
https://github.com/python-kasa/python-kasa.git
synced 2024-12-23 11:43:34 +00:00
Merge branch 'master' into dump_devinfo
This commit is contained in:
commit
838370a8a8
109
CHANGELOG.md
109
CHANGELOG.md
@ -1,8 +1,89 @@
|
||||
# Changelog
|
||||
|
||||
## [0.8.1](https://github.com/python-kasa/python-kasa/tree/0.8.1) (2024-12-06)
|
||||
## [0.9.0](https://github.com/python-kasa/python-kasa/tree/0.9.0) (2024-12-21)
|
||||
|
||||
This patch release fixes some issues with newly supported smartcam devices.
|
||||
[Full Changelog](https://github.com/python-kasa/python-kasa/compare/0.8.1...0.9.0)
|
||||
|
||||
**Release highlights:**
|
||||
|
||||
- Improvements to Tapo camera support:
|
||||
- C100, C225, C325WB, C520WS and TC70 now supported.
|
||||
- Support for motion, person, tamper, and baby cry detection.
|
||||
- Initial support for Tapo robovacs.
|
||||
- API extended with `FeatureAttributes` for consumers to test for [supported features](https://python-kasa.readthedocs.io/en/stable/topics.html#modules-and-features).
|
||||
- Experimental support for Kasa cameras[^1]
|
||||
|
||||
[^1]: Currently limited to devices not yet provisioned via the Tapo app - Many thanks to @puxtril!
|
||||
|
||||
**Breaking changes:**
|
||||
|
||||
- Use DeviceInfo consistently across devices [\#1338](https://github.com/python-kasa/python-kasa/pull/1338) (@sdb9696)
|
||||
|
||||
**Implemented enhancements:**
|
||||
|
||||
- Add rssi and signal\_level to smartcam [\#1392](https://github.com/python-kasa/python-kasa/pull/1392) (@sdb9696)
|
||||
- Add smartcam detection modules [\#1389](https://github.com/python-kasa/python-kasa/pull/1389) (@sdb9696)
|
||||
- Add bare-bones matter modules to smart and smartcam devices [\#1371](https://github.com/python-kasa/python-kasa/pull/1371) (@sdb9696)
|
||||
- Add bare bones homekit modules smart and smartcam devices [\#1370](https://github.com/python-kasa/python-kasa/pull/1370) (@sdb9696)
|
||||
- Return raw discovery result in cli discover raw [\#1342](https://github.com/python-kasa/python-kasa/pull/1342) (@sdb9696)
|
||||
- cli: print model, https, and lv for discover list [\#1339](https://github.com/python-kasa/python-kasa/pull/1339) (@rytilahti)
|
||||
- Improve overheat reporting [\#1335](https://github.com/python-kasa/python-kasa/pull/1335) (@rytilahti)
|
||||
- Provide alternative camera urls [\#1316](https://github.com/python-kasa/python-kasa/pull/1316) (@sdb9696)
|
||||
- Add LinkieTransportV2 and basic IOT.IPCAMERA support [\#1270](https://github.com/python-kasa/python-kasa/pull/1270) (@Puxtril)
|
||||
- Add ssltransport for robovacs [\#943](https://github.com/python-kasa/python-kasa/pull/943) (@rytilahti)
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- Tapo H200 Hub does not work with python-kasa [\#1149](https://github.com/python-kasa/python-kasa/issues/1149)
|
||||
- Treat smartcam 500 errors after handshake as retryable [\#1395](https://github.com/python-kasa/python-kasa/pull/1395) (@sdb9696)
|
||||
- Fix lens mask required component and state [\#1386](https://github.com/python-kasa/python-kasa/pull/1386) (@sdb9696)
|
||||
- Add LensMask module to smartcam [\#1385](https://github.com/python-kasa/python-kasa/pull/1385) (@sdb9696)
|
||||
- Do not error when accessing smart device\_type before update [\#1319](https://github.com/python-kasa/python-kasa/pull/1319) (@sdb9696)
|
||||
- Fallback to other module data on get\_energy\_usage errors [\#1245](https://github.com/python-kasa/python-kasa/pull/1245) (@rytilahti)
|
||||
|
||||
**Added support for devices:**
|
||||
|
||||
- Add P210M\(US\) 1.0 1.0.3 fixture [\#1399](https://github.com/python-kasa/python-kasa/pull/1399) (@sdb9696)
|
||||
- Add C225\(US\) 2.0 1.0.11 fixture [\#1398](https://github.com/python-kasa/python-kasa/pull/1398) (@sdb9696)
|
||||
- Add P306\(US\) 1.0 1.1.2 fixture [\#1396](https://github.com/python-kasa/python-kasa/pull/1396) (@nakanaela)
|
||||
- Add TC70 3.0 1.3.11 fixture [\#1390](https://github.com/python-kasa/python-kasa/pull/1390) (@sdb9696)
|
||||
- Add C325WB\(EU\) 1.0 1.1.17 Fixture [\#1379](https://github.com/python-kasa/python-kasa/pull/1379) (@sdb9696)
|
||||
- Add C100 4.0 1.3.14 Fixture [\#1378](https://github.com/python-kasa/python-kasa/pull/1378) (@sdb9696)
|
||||
- Add KS200 \(US\) IOT Fixture and P115 \(US\) Smart Fixture [\#1355](https://github.com/python-kasa/python-kasa/pull/1355) (@ZeliardM)
|
||||
- Add C520WS camera fixture [\#1352](https://github.com/python-kasa/python-kasa/pull/1352) (@Happy-Cadaver)
|
||||
|
||||
**Documentation updates:**
|
||||
|
||||
- Update docs for Tapo Lab Third-Party compatibility [\#1380](https://github.com/python-kasa/python-kasa/pull/1380) (@sdb9696)
|
||||
- Add homebridge-kasa-python link to README [\#1367](https://github.com/python-kasa/python-kasa/pull/1367) (@rytilahti)
|
||||
- Update docs for new FeatureAttribute behaviour [\#1365](https://github.com/python-kasa/python-kasa/pull/1365) (@sdb9696)
|
||||
- Add link to related homeassistant-tapo-control [\#1333](https://github.com/python-kasa/python-kasa/pull/1333) (@rytilahti)
|
||||
|
||||
**Project maintenance:**
|
||||
|
||||
- Add P135 1.0 1.2.0 fixture [\#1397](https://github.com/python-kasa/python-kasa/pull/1397) (@sdb9696)
|
||||
- Handle smartcam device blocked response [\#1393](https://github.com/python-kasa/python-kasa/pull/1393) (@sdb9696)
|
||||
- Handle KeyboardInterrupts in the cli better [\#1391](https://github.com/python-kasa/python-kasa/pull/1391) (@sdb9696)
|
||||
- Update C520WS fixture with new methods [\#1384](https://github.com/python-kasa/python-kasa/pull/1384) (@sdb9696)
|
||||
- Miscellaneous minor fixes to dump\_devinfo [\#1382](https://github.com/python-kasa/python-kasa/pull/1382) (@sdb9696)
|
||||
- Add timeout parameter to dump\_devinfo [\#1381](https://github.com/python-kasa/python-kasa/pull/1381) (@sdb9696)
|
||||
- Simplify get\_protocol to prevent clashes with smartcam and robovac [\#1377](https://github.com/python-kasa/python-kasa/pull/1377) (@sdb9696)
|
||||
- Add smartcam modules to package inits [\#1376](https://github.com/python-kasa/python-kasa/pull/1376) (@sdb9696)
|
||||
- Enable saving of fixture files without git clone [\#1375](https://github.com/python-kasa/python-kasa/pull/1375) (@sdb9696)
|
||||
- Force single for some smartcam requests [\#1374](https://github.com/python-kasa/python-kasa/pull/1374) (@sdb9696)
|
||||
- Add new methods to dump\_devinfo [\#1373](https://github.com/python-kasa/python-kasa/pull/1373) (@sdb9696)
|
||||
- Update cli, light modules, and docs to use FeatureAttributes [\#1364](https://github.com/python-kasa/python-kasa/pull/1364) (@sdb9696)
|
||||
- Pass raw components to SmartChildDevice init [\#1363](https://github.com/python-kasa/python-kasa/pull/1363) (@sdb9696)
|
||||
- Fix line endings in device\_fixtures.py [\#1361](https://github.com/python-kasa/python-kasa/pull/1361) (@sdb9696)
|
||||
- Update dump\_devinfo for raw discovery json and common redactors [\#1358](https://github.com/python-kasa/python-kasa/pull/1358) (@sdb9696)
|
||||
- Tweak RELEASING.md instructions for patch releases [\#1347](https://github.com/python-kasa/python-kasa/pull/1347) (@sdb9696)
|
||||
- Scrub more vacuum keys [\#1328](https://github.com/python-kasa/python-kasa/pull/1328) (@rytilahti)
|
||||
- Remove unnecessary check for python \<3.10 [\#1326](https://github.com/python-kasa/python-kasa/pull/1326) (@rytilahti)
|
||||
- Add vacuum component queries to dump\_devinfo [\#1320](https://github.com/python-kasa/python-kasa/pull/1320) (@rytilahti)
|
||||
- Handle missing mgt\_encryption\_schm in discovery [\#1318](https://github.com/python-kasa/python-kasa/pull/1318) (@sdb9696)
|
||||
- Follow main package structure for tests [\#1317](https://github.com/python-kasa/python-kasa/pull/1317) (@rytilahti)
|
||||
|
||||
## [0.8.1](https://github.com/python-kasa/python-kasa/tree/0.8.1) (2024-12-06)
|
||||
|
||||
[Full Changelog](https://github.com/python-kasa/python-kasa/compare/0.8.0...0.8.1)
|
||||
|
||||
@ -46,28 +127,28 @@ Special thanks to @ryenitcher and @Puxtril for their new contributions to the im
|
||||
- Update cli feature command for actions not to require a value [\#1264](https://github.com/python-kasa/python-kasa/pull/1264) (@sdb9696)
|
||||
- Add pan tilt camera module [\#1261](https://github.com/python-kasa/python-kasa/pull/1261) (@sdb9696)
|
||||
- Add alarm module for smartcamera hubs [\#1258](https://github.com/python-kasa/python-kasa/pull/1258) (@sdb9696)
|
||||
- Move TAPO smartcamera out of experimental package [\#1255](https://github.com/python-kasa/python-kasa/pull/1255) (@sdb9696)
|
||||
- Add SmartCamera Led Module [\#1249](https://github.com/python-kasa/python-kasa/pull/1249) (@sdb9696)
|
||||
- Use component queries to select smartcamera modules [\#1248](https://github.com/python-kasa/python-kasa/pull/1248) (@sdb9696)
|
||||
- Print formatting for IotLightPreset [\#1216](https://github.com/python-kasa/python-kasa/pull/1216) (@Puxtril)
|
||||
- Allow getting Annotated features from modules [\#1018](https://github.com/python-kasa/python-kasa/pull/1018) (@sdb9696)
|
||||
- Move TAPO smartcamera out of experimental package [\#1255](https://github.com/python-kasa/python-kasa/pull/1255) (@sdb9696)
|
||||
- Use component queries to select smartcamera modules [\#1248](https://github.com/python-kasa/python-kasa/pull/1248) (@sdb9696)
|
||||
- Add common Thermostat module [\#977](https://github.com/python-kasa/python-kasa/pull/977) (@sdb9696)
|
||||
|
||||
**Fixed bugs:**
|
||||
|
||||
- TP-Link Tapo S505D cannot disable gradual on/off [\#1309](https://github.com/python-kasa/python-kasa/issues/1309)
|
||||
- Inconsistent emeter information between features and emeter cli [\#1308](https://github.com/python-kasa/python-kasa/issues/1308)
|
||||
- How to dump power usage after latest updates? [\#1306](https://github.com/python-kasa/python-kasa/issues/1306)
|
||||
- kasa.discover: Got unsupported connection type: 'device\_family': 'SMART.IPCAMERA' [\#1267](https://github.com/python-kasa/python-kasa/issues/1267)
|
||||
- device \_\_repr\_\_ fails if no sys\_info [\#1262](https://github.com/python-kasa/python-kasa/issues/1262)
|
||||
- Tapo P110M: Error processing Energy for device, module will be unavailable: get\_energy\_usage for Energy [\#1243](https://github.com/python-kasa/python-kasa/issues/1243)
|
||||
- Listing light presets throws error [\#1201](https://github.com/python-kasa/python-kasa/issues/1201)
|
||||
- Include duration when disabling smooth transition on/off [\#1313](https://github.com/python-kasa/python-kasa/pull/1313) (@rytilahti)
|
||||
- Expose energy command to cli [\#1307](https://github.com/python-kasa/python-kasa/pull/1307) (@rytilahti)
|
||||
- Inconsistent emeter information between features and emeter cli [\#1308](https://github.com/python-kasa/python-kasa/issues/1308)
|
||||
- Make discovery on unsupported devices less noisy [\#1291](https://github.com/python-kasa/python-kasa/pull/1291) (@rytilahti)
|
||||
- Fix repr for device created with no sysinfo or discovery info" [\#1266](https://github.com/python-kasa/python-kasa/pull/1266) (@sdb9696)
|
||||
- Fix discovery by alias for smart devices [\#1260](https://github.com/python-kasa/python-kasa/pull/1260) (@sdb9696)
|
||||
- Make \_\_repr\_\_ work on discovery info [\#1233](https://github.com/python-kasa/python-kasa/pull/1233) (@rytilahti)
|
||||
- Include duration when disabling smooth transition on/off [\#1313](https://github.com/python-kasa/python-kasa/pull/1313) (@rytilahti)
|
||||
- Expose energy command to cli [\#1307](https://github.com/python-kasa/python-kasa/pull/1307) (@rytilahti)
|
||||
|
||||
**Added support for devices:**
|
||||
|
||||
@ -81,13 +162,11 @@ Special thanks to @ryenitcher and @Puxtril for their new contributions to the im
|
||||
**Documentation updates:**
|
||||
|
||||
- Use markdown footnotes in supported.md [\#1310](https://github.com/python-kasa/python-kasa/pull/1310) (@sdb9696)
|
||||
- Update docs for the new module attributes has/get feature [\#1301](https://github.com/python-kasa/python-kasa/pull/1301) (@sdb9696)
|
||||
- Fixup contributing.md for running test against a real device [\#1236](https://github.com/python-kasa/python-kasa/pull/1236) (@sdb9696)
|
||||
- Update docs for the new module attributes has/get feature [\#1301](https://github.com/python-kasa/python-kasa/pull/1301) (@sdb9696)
|
||||
|
||||
**Project maintenance:**
|
||||
|
||||
- Rename tests/smartcamera to tests/smartcam [\#1315](https://github.com/python-kasa/python-kasa/pull/1315) (@sdb9696)
|
||||
- Do not error on smartcam hub attached smartcam child devices [\#1314](https://github.com/python-kasa/python-kasa/pull/1314) (@sdb9696)
|
||||
- Add P110M\(EU\) fixture [\#1305](https://github.com/python-kasa/python-kasa/pull/1305) (@sdb9696)
|
||||
- Run tests with caplog in a single worker [\#1304](https://github.com/python-kasa/python-kasa/pull/1304) (@sdb9696)
|
||||
- Rename smartcamera to smartcam [\#1300](https://github.com/python-kasa/python-kasa/pull/1300) (@sdb9696)
|
||||
@ -117,15 +196,17 @@ Special thanks to @ryenitcher and @Puxtril for their new contributions to the im
|
||||
- Add linkcheck to readthedocs CI [\#1253](https://github.com/python-kasa/python-kasa/pull/1253) (@rytilahti)
|
||||
- Update cli energy command to use energy module [\#1252](https://github.com/python-kasa/python-kasa/pull/1252) (@sdb9696)
|
||||
- Consolidate warnings for fixtures missing child devices [\#1251](https://github.com/python-kasa/python-kasa/pull/1251) (@sdb9696)
|
||||
- Update smartcamera fixtures with components [\#1250](https://github.com/python-kasa/python-kasa/pull/1250) (@sdb9696)
|
||||
- Move transports into their own package [\#1247](https://github.com/python-kasa/python-kasa/pull/1247) (@rytilahti)
|
||||
- Fix warnings in our test suite [\#1246](https://github.com/python-kasa/python-kasa/pull/1246) (@rytilahti)
|
||||
- Move tests folder to top level of project [\#1242](https://github.com/python-kasa/python-kasa/pull/1242) (@sdb9696)
|
||||
- Fix test framework running against real devices [\#1235](https://github.com/python-kasa/python-kasa/pull/1235) (@sdb9696)
|
||||
- Add Additional Firmware Test Fixures [\#1234](https://github.com/python-kasa/python-kasa/pull/1234) (@ryenitcher)
|
||||
- Update DiscoveryResult to use Mashumaro instead of pydantic [\#1231](https://github.com/python-kasa/python-kasa/pull/1231) (@sdb9696)
|
||||
- Update fixture for ES20M 1.0.11 [\#1215](https://github.com/python-kasa/python-kasa/pull/1215) (@rytilahti)
|
||||
- Enable ruff check for ANN [\#1139](https://github.com/python-kasa/python-kasa/pull/1139) (@rytilahti)
|
||||
- Rename tests/smartcamera to tests/smartcam [\#1315](https://github.com/python-kasa/python-kasa/pull/1315) (@sdb9696)
|
||||
- Do not error on smartcam hub attached smartcam child devices [\#1314](https://github.com/python-kasa/python-kasa/pull/1314) (@sdb9696)
|
||||
- Update smartcamera fixtures with components [\#1250](https://github.com/python-kasa/python-kasa/pull/1250) (@sdb9696)
|
||||
- Fix warnings in our test suite [\#1246](https://github.com/python-kasa/python-kasa/pull/1246) (@rytilahti)
|
||||
- Fix test framework running against real devices [\#1235](https://github.com/python-kasa/python-kasa/pull/1235) (@sdb9696)
|
||||
- Update DiscoveryResult to use Mashumaro instead of pydantic [\#1231](https://github.com/python-kasa/python-kasa/pull/1231) (@sdb9696)
|
||||
|
||||
**Closed issues:**
|
||||
|
||||
|
@ -197,11 +197,11 @@ The following devices have been tested and confirmed as working. If your device
|
||||
### Supported Tapo[^1] devices
|
||||
|
||||
- **Plugs**: P100, P110, P110M, P115, P125M, P135, TP15
|
||||
- **Power Strips**: P300, P304M, TP25
|
||||
- **Power Strips**: P210M, P300, P304M, P306, TP25
|
||||
- **Wall Switches**: S500D, S505, S505D
|
||||
- **Bulbs**: L510B, L510E, L530E, L630
|
||||
- **Light Strips**: L900-10, L900-5, L920-5, L930-5
|
||||
- **Cameras**: C210, C520WS, TC65
|
||||
- **Cameras**: C100, C210, C225, C325WB, C520WS, TC65, TC70
|
||||
- **Hubs**: H100, H200
|
||||
- **Hub-Connected Devices[^3]**: S200B, S200D, T100, T110, T300, T310, T315
|
||||
|
||||
|
13
SUPPORTED.md
13
SUPPORTED.md
@ -202,17 +202,22 @@ All Tapo devices require authentication.<br>Hub-Connected Devices may work acros
|
||||
- Hardware: 1.0 (US) / Firmware: 1.1.0
|
||||
- **P135**
|
||||
- Hardware: 1.0 (US) / Firmware: 1.0.5
|
||||
- Hardware: 1.0 (US) / Firmware: 1.2.0
|
||||
- **TP15**
|
||||
- Hardware: 1.0 (US) / Firmware: 1.0.3
|
||||
|
||||
### Power Strips
|
||||
|
||||
- **P210M**
|
||||
- Hardware: 1.0 (US) / Firmware: 1.0.3
|
||||
- **P300**
|
||||
- Hardware: 1.0 (EU) / Firmware: 1.0.13
|
||||
- Hardware: 1.0 (EU) / Firmware: 1.0.15
|
||||
- Hardware: 1.0 (EU) / Firmware: 1.0.7
|
||||
- **P304M**
|
||||
- Hardware: 1.0 (UK) / Firmware: 1.0.3
|
||||
- **P306**
|
||||
- Hardware: 1.0 (US) / Firmware: 1.1.2
|
||||
- **TP25**
|
||||
- Hardware: 1.0 (US) / Firmware: 1.0.2
|
||||
|
||||
@ -258,13 +263,21 @@ All Tapo devices require authentication.<br>Hub-Connected Devices may work acros
|
||||
|
||||
### Cameras
|
||||
|
||||
- **C100**
|
||||
- Hardware: 4.0 / Firmware: 1.3.14
|
||||
- **C210**
|
||||
- Hardware: 2.0 (EU) / Firmware: 1.4.2
|
||||
- Hardware: 2.0 (EU) / Firmware: 1.4.3
|
||||
- **C225**
|
||||
- Hardware: 2.0 (US) / Firmware: 1.0.11
|
||||
- **C325WB**
|
||||
- Hardware: 1.0 (EU) / Firmware: 1.1.17
|
||||
- **C520WS**
|
||||
- Hardware: 1.0 (US) / Firmware: 1.2.8
|
||||
- **TC65**
|
||||
- Hardware: 1.0 / Firmware: 1.3.9
|
||||
- **TC70**
|
||||
- Hardware: 3.0 / Firmware: 1.3.11
|
||||
|
||||
### Hubs
|
||||
|
||||
|
@ -2,12 +2,14 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import asyncio
|
||||
import json
|
||||
import re
|
||||
import sys
|
||||
from collections.abc import Callable
|
||||
from contextlib import contextmanager
|
||||
from functools import singledispatch, update_wrapper, wraps
|
||||
from gettext import gettext
|
||||
from typing import TYPE_CHECKING, Any, Final
|
||||
|
||||
import asyncclick as click
|
||||
@ -238,4 +240,19 @@ def CatchAllExceptions(cls):
|
||||
except Exception as exc:
|
||||
_handle_exception(self._debug, exc)
|
||||
|
||||
def __call__(self, *args, **kwargs):
|
||||
"""Run the coroutine in the event loop and print any exceptions.
|
||||
|
||||
python click catches KeyboardInterrupt in main, raises Abort()
|
||||
and does sys.exit. asyncclick doesn't properly handle a coroutine
|
||||
receiving CancelledError on a KeyboardInterrupt, so we catch the
|
||||
KeyboardInterrupt here once asyncio.run has re-raised it. This
|
||||
avoids large stacktraces when a user presses Ctrl-C.
|
||||
"""
|
||||
try:
|
||||
asyncio.run(self.main(*args, **kwargs))
|
||||
except KeyboardInterrupt:
|
||||
click.echo(gettext("\nAborted!"), file=sys.stderr)
|
||||
sys.exit(1)
|
||||
|
||||
return _CommandCls
|
||||
|
@ -123,14 +123,19 @@ async def list(ctx):
|
||||
async def print_discovered(dev: Device):
|
||||
cparams = dev.config.connection_type
|
||||
infostr = (
|
||||
f"{dev.host:<15} {cparams.device_family.value:<20} "
|
||||
f"{cparams.encryption_type.value:<7}"
|
||||
f"{dev.host:<15} {dev.model:<9} {cparams.device_family.value:<20} "
|
||||
f"{cparams.encryption_type.value:<7} {cparams.https:<5} "
|
||||
f"{cparams.login_version or '-':<3}"
|
||||
)
|
||||
async with sem:
|
||||
try:
|
||||
await dev.update()
|
||||
except AuthenticationError:
|
||||
echo(f"{infostr} - Authentication failed")
|
||||
except TimeoutError:
|
||||
echo(f"{infostr} - Timed out")
|
||||
except Exception as ex:
|
||||
echo(f"{infostr} - Error: {ex}")
|
||||
else:
|
||||
echo(f"{infostr} {dev.alias}")
|
||||
|
||||
@ -138,7 +143,10 @@ async def list(ctx):
|
||||
if host := unsupported_exception.host:
|
||||
echo(f"{host:<15} UNSUPPORTED DEVICE")
|
||||
|
||||
echo(f"{'HOST':<15} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} {'ALIAS'}")
|
||||
echo(
|
||||
f"{'HOST':<15} {'MODEL':<9} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} "
|
||||
f"{'HTTPS':<5} {'LV':<3} {'ALIAS'}"
|
||||
)
|
||||
return await _discover(
|
||||
ctx,
|
||||
print_discovered=print_discovered,
|
||||
|
@ -8,7 +8,7 @@ from typing import Any
|
||||
|
||||
from .device import Device
|
||||
from .device_type import DeviceType
|
||||
from .deviceconfig import DeviceConfig
|
||||
from .deviceconfig import DeviceConfig, DeviceFamily
|
||||
from .exceptions import KasaException, UnsupportedDeviceError
|
||||
from .iot import (
|
||||
IotBulb,
|
||||
@ -179,20 +179,29 @@ def get_device_class_from_family(
|
||||
def get_protocol(
|
||||
config: DeviceConfig,
|
||||
) -> BaseProtocol | None:
|
||||
"""Return the protocol from the connection name."""
|
||||
protocol_name = config.connection_type.device_family.value.split(".")[0]
|
||||
"""Return the protocol from the connection name.
|
||||
|
||||
For cameras and vacuums the device family is a simple mapping to
|
||||
the protocol/transport. For other device types the transport varies
|
||||
based on the discovery information.
|
||||
"""
|
||||
ctype = config.connection_type
|
||||
protocol_name = ctype.device_family.value.split(".")[0]
|
||||
|
||||
if ctype.device_family is DeviceFamily.SmartIpCamera:
|
||||
return SmartCamProtocol(transport=SslAesTransport(config=config))
|
||||
|
||||
if ctype.device_family is DeviceFamily.IotIpCamera:
|
||||
return IotProtocol(transport=LinkieTransportV2(config=config))
|
||||
|
||||
if ctype.device_family is DeviceFamily.SmartTapoRobovac:
|
||||
return SmartProtocol(transport=SslTransport(config=config))
|
||||
|
||||
protocol_transport_key = (
|
||||
protocol_name
|
||||
+ "."
|
||||
+ ctype.encryption_type.value
|
||||
+ (".HTTPS" if ctype.https else "")
|
||||
+ (
|
||||
f".{ctype.login_version}"
|
||||
if ctype.login_version and ctype.login_version > 1
|
||||
else ""
|
||||
)
|
||||
)
|
||||
|
||||
_LOGGER.debug("Finding transport for %s", protocol_transport_key)
|
||||
@ -201,12 +210,11 @@ def get_protocol(
|
||||
] = {
|
||||
"IOT.XOR": (IotProtocol, XorTransport),
|
||||
"IOT.KLAP": (IotProtocol, KlapTransport),
|
||||
"IOT.XOR.HTTPS.2": (IotProtocol, LinkieTransportV2),
|
||||
"SMART.AES": (SmartProtocol, AesTransport),
|
||||
"SMART.AES.2": (SmartProtocol, AesTransport),
|
||||
"SMART.KLAP.2": (SmartProtocol, KlapTransportV2),
|
||||
"SMART.AES.HTTPS.2": (SmartCamProtocol, SslAesTransport),
|
||||
"SMART.AES.HTTPS": (SmartProtocol, SslTransport),
|
||||
"SMART.KLAP": (SmartProtocol, KlapTransportV2),
|
||||
# H200 is device family SMART.TAPOHUB and uses SmartCamProtocol so use
|
||||
# https to distuingish from SmartProtocol devices
|
||||
"SMART.AES.HTTPS": (SmartCamProtocol, SslAesTransport),
|
||||
}
|
||||
if not (prot_tran_cls := supported_device_protocols.get(protocol_transport_key)):
|
||||
return None
|
||||
|
@ -498,7 +498,7 @@ class Discover:
|
||||
try:
|
||||
_LOGGER.debug("Waiting %s seconds for responses...", discovery_timeout)
|
||||
await protocol.wait_for_discovery_to_complete()
|
||||
except KasaException as ex:
|
||||
except (KasaException, asyncio.CancelledError) as ex:
|
||||
for device in protocol.discovered_devices.values():
|
||||
await device.protocol.close()
|
||||
raise ex
|
||||
@ -847,12 +847,12 @@ class Discover:
|
||||
):
|
||||
encrypt_type = encrypt_info.sym_schm
|
||||
|
||||
if (
|
||||
not (login_version := encrypt_schm.lv)
|
||||
and (et := discovery_result.encrypt_type)
|
||||
and et == ["3"]
|
||||
if not (login_version := encrypt_schm.lv) and (
|
||||
et := discovery_result.encrypt_type
|
||||
):
|
||||
login_version = 2
|
||||
# Known encrypt types are ["1","2"] and ["3"]
|
||||
# Reuse the login_version attribute to pass the max to transport
|
||||
login_version = max([int(i) for i in et])
|
||||
|
||||
if not encrypt_type:
|
||||
raise UnsupportedDeviceError(
|
||||
|
@ -113,10 +113,23 @@ class HttpClient:
|
||||
ssl=ssl,
|
||||
)
|
||||
async with resp:
|
||||
if resp.status == 200:
|
||||
response_data = await resp.read()
|
||||
if return_json:
|
||||
response_data = await resp.read()
|
||||
|
||||
if resp.status == 200:
|
||||
if return_json:
|
||||
response_data = json_loads(response_data.decode())
|
||||
else:
|
||||
_LOGGER.debug(
|
||||
"Device %s received status code %s with response %s",
|
||||
self._config.host,
|
||||
resp.status,
|
||||
str(response_data),
|
||||
)
|
||||
if response_data and return_json:
|
||||
try:
|
||||
response_data = json_loads(response_data.decode())
|
||||
except Exception:
|
||||
_LOGGER.debug("Device %s response could not be parsed as json")
|
||||
|
||||
except (aiohttp.ServerDisconnectedError, aiohttp.ClientOSError) as ex:
|
||||
if not self._wait_between_requests:
|
||||
|
@ -159,6 +159,7 @@ class Module(ABC):
|
||||
|
||||
# SMARTCAM only modules
|
||||
Camera: Final[ModuleName[smartcam.Camera]] = ModuleName("Camera")
|
||||
LensMask: Final[ModuleName[smartcam.LensMask]] = ModuleName("LensMask")
|
||||
|
||||
def __init__(self, device: Device, module: str) -> None:
|
||||
self._device = device
|
||||
|
@ -2,10 +2,10 @@
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from typing import NoReturn
|
||||
from typing import Any, NoReturn
|
||||
|
||||
from ...emeterstatus import EmeterStatus
|
||||
from ...exceptions import KasaException
|
||||
from ...exceptions import DeviceError, KasaException
|
||||
from ...interfaces.energy import Energy as EnergyInterface
|
||||
from ..smartmodule import SmartModule, raise_if_update_error
|
||||
|
||||
@ -15,12 +15,39 @@ class Energy(SmartModule, EnergyInterface):
|
||||
|
||||
REQUIRED_COMPONENT = "energy_monitoring"
|
||||
|
||||
_energy: dict[str, Any]
|
||||
_current_consumption: float | None
|
||||
|
||||
async def _post_update_hook(self) -> None:
|
||||
if "voltage_mv" in self.data.get("get_emeter_data", {}):
|
||||
try:
|
||||
data = self.data
|
||||
except DeviceError as de:
|
||||
self._energy = {}
|
||||
self._current_consumption = None
|
||||
raise de
|
||||
|
||||
# If version is 1 then data is get_energy_usage
|
||||
self._energy = data.get("get_energy_usage", data)
|
||||
|
||||
if "voltage_mv" in data.get("get_emeter_data", {}):
|
||||
self._supported = (
|
||||
self._supported | EnergyInterface.ModuleFeature.VOLTAGE_CURRENT
|
||||
)
|
||||
|
||||
if (power := self._energy.get("current_power")) is not None or (
|
||||
power := data.get("get_emeter_data", {}).get("power_mw")
|
||||
) is not None:
|
||||
self._current_consumption = power / 1_000
|
||||
# Fallback if get_energy_usage does not provide current_power,
|
||||
# which can happen on some newer devices (e.g. P304M).
|
||||
# This may not be valid scenario as it pre-dates trying get_emeter_data
|
||||
elif (
|
||||
power := self.data.get("get_current_power", {}).get("current_power")
|
||||
) is not None:
|
||||
self._current_consumption = power
|
||||
else:
|
||||
self._current_consumption = None
|
||||
|
||||
def query(self) -> dict:
|
||||
"""Query to execute during the update cycle."""
|
||||
req = {
|
||||
@ -33,28 +60,21 @@ class Energy(SmartModule, EnergyInterface):
|
||||
return req
|
||||
|
||||
@property
|
||||
@raise_if_update_error
|
||||
def current_consumption(self) -> float | None:
|
||||
"""Current power in watts."""
|
||||
if (power := self.energy.get("current_power")) is not None or (
|
||||
power := self.data.get("get_emeter_data", {}).get("power_mw")
|
||||
) is not None:
|
||||
return power / 1_000
|
||||
# Fallback if get_energy_usage does not provide current_power,
|
||||
# which can happen on some newer devices (e.g. P304M).
|
||||
elif (
|
||||
power := self.data.get("get_current_power", {}).get("current_power")
|
||||
) is not None:
|
||||
return power
|
||||
return None
|
||||
def optional_response_keys(self) -> list[str]:
|
||||
"""Return optional response keys for the module."""
|
||||
if self.supported_version > 1:
|
||||
return ["get_energy_usage"]
|
||||
return []
|
||||
|
||||
@property
|
||||
def current_consumption(self) -> float | None:
|
||||
"""Current power in watts."""
|
||||
return self._current_consumption
|
||||
|
||||
@property
|
||||
@raise_if_update_error
|
||||
def energy(self) -> dict:
|
||||
"""Return get_energy_usage results."""
|
||||
if en := self.data.get("get_energy_usage"):
|
||||
return en
|
||||
return self.data
|
||||
return self._energy
|
||||
|
||||
def _get_status_from_energy(self, energy: dict) -> EmeterStatus:
|
||||
return EmeterStatus(
|
||||
@ -83,16 +103,18 @@ class Energy(SmartModule, EnergyInterface):
|
||||
return self._get_status_from_energy(res["get_energy_usage"])
|
||||
|
||||
@property
|
||||
@raise_if_update_error
|
||||
def consumption_this_month(self) -> float | None:
|
||||
"""Get the emeter value for this month in kWh."""
|
||||
return self.energy.get("month_energy", 0) / 1_000
|
||||
if (month := self.energy.get("month_energy")) is not None:
|
||||
return month / 1_000
|
||||
return None
|
||||
|
||||
@property
|
||||
@raise_if_update_error
|
||||
def consumption_today(self) -> float | None:
|
||||
"""Get the emeter value for today in kWh."""
|
||||
return self.energy.get("today_energy", 0) / 1_000
|
||||
if (today := self.energy.get("today_energy")) is not None:
|
||||
return today / 1_000
|
||||
return None
|
||||
|
||||
@property
|
||||
@raise_if_update_error
|
||||
|
@ -72,6 +72,7 @@ class SmartModule(Module):
|
||||
self._last_update_time: float | None = None
|
||||
self._last_update_error: KasaException | None = None
|
||||
self._error_count = 0
|
||||
self._logged_remove_keys: list[str] = []
|
||||
|
||||
def __init_subclass__(cls, **kwargs) -> None:
|
||||
# We only want to register submodules in a modules package so that
|
||||
@ -149,6 +150,15 @@ class SmartModule(Module):
|
||||
"""
|
||||
return await self._device._query_helper(method, params)
|
||||
|
||||
@property
|
||||
def optional_response_keys(self) -> list[str]:
|
||||
"""Return optional response keys for the module.
|
||||
|
||||
Defaults to no keys. Overriding this and providing keys will remove
|
||||
instead of raise on error.
|
||||
"""
|
||||
return []
|
||||
|
||||
@property
|
||||
def data(self) -> dict[str, Any]:
|
||||
"""Return response data for the module.
|
||||
@ -181,12 +191,31 @@ class SmartModule(Module):
|
||||
|
||||
filtered_data = {k: v for k, v in dev._last_update.items() if k in q_keys}
|
||||
|
||||
remove_keys: list[str] = []
|
||||
for data_item in filtered_data:
|
||||
if isinstance(filtered_data[data_item], SmartErrorCode):
|
||||
raise DeviceError(
|
||||
f"{data_item} for {self.name}", error_code=filtered_data[data_item]
|
||||
if data_item in self.optional_response_keys:
|
||||
remove_keys.append(data_item)
|
||||
else:
|
||||
raise DeviceError(
|
||||
f"{data_item} for {self.name}",
|
||||
error_code=filtered_data[data_item],
|
||||
)
|
||||
|
||||
for key in remove_keys:
|
||||
if key not in self._logged_remove_keys:
|
||||
self._logged_remove_keys.append(key)
|
||||
_LOGGER.debug(
|
||||
"Removed key %s from response for device %s as it returned "
|
||||
"error: %s. This message will only be logged once per key.",
|
||||
key,
|
||||
self._device.host,
|
||||
filtered_data[key],
|
||||
)
|
||||
if len(filtered_data) == 1:
|
||||
|
||||
filtered_data.pop(key)
|
||||
|
||||
if len(filtered_data) == 1 and not remove_keys:
|
||||
return next(iter(filtered_data.values()))
|
||||
|
||||
return filtered_data
|
||||
|
@ -1,23 +1,33 @@
|
||||
"""Modules for SMARTCAM devices."""
|
||||
|
||||
from .alarm import Alarm
|
||||
from .babycrydetection import BabyCryDetection
|
||||
from .camera import Camera
|
||||
from .childdevice import ChildDevice
|
||||
from .device import DeviceModule
|
||||
from .homekit import HomeKit
|
||||
from .led import Led
|
||||
from .lensmask import LensMask
|
||||
from .matter import Matter
|
||||
from .motiondetection import MotionDetection
|
||||
from .pantilt import PanTilt
|
||||
from .persondetection import PersonDetection
|
||||
from .tamperdetection import TamperDetection
|
||||
from .time import Time
|
||||
|
||||
__all__ = [
|
||||
"Alarm",
|
||||
"BabyCryDetection",
|
||||
"Camera",
|
||||
"ChildDevice",
|
||||
"DeviceModule",
|
||||
"Led",
|
||||
"PanTilt",
|
||||
"PersonDetection",
|
||||
"Time",
|
||||
"HomeKit",
|
||||
"Matter",
|
||||
"MotionDetection",
|
||||
"LensMask",
|
||||
"TamperDetection",
|
||||
]
|
||||
|
47
kasa/smartcam/modules/babycrydetection.py
Normal file
47
kasa/smartcam/modules/babycrydetection.py
Normal file
@ -0,0 +1,47 @@
|
||||
"""Implementation of baby cry detection module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from ...feature import Feature
|
||||
from ..smartcammodule import SmartCamModule
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class BabyCryDetection(SmartCamModule):
|
||||
"""Implementation of baby cry detection module."""
|
||||
|
||||
REQUIRED_COMPONENT = "babyCryDetection"
|
||||
|
||||
QUERY_GETTER_NAME = "getBCDConfig"
|
||||
QUERY_MODULE_NAME = "sound_detection"
|
||||
QUERY_SECTION_NAMES = "bcd"
|
||||
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
self._device,
|
||||
id="baby_cry_detection",
|
||||
name="Baby cry detection",
|
||||
container=self,
|
||||
attribute_getter="enabled",
|
||||
attribute_setter="set_enabled",
|
||||
type=Feature.Type.Switch,
|
||||
category=Feature.Category.Primary,
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def enabled(self) -> bool:
|
||||
"""Return the baby cry detection enabled state."""
|
||||
return self.data["bcd"]["enabled"] == "on"
|
||||
|
||||
async def set_enabled(self, enable: bool) -> dict:
|
||||
"""Set the baby cry detection enabled state."""
|
||||
params = {"enabled": "on" if enable else "off"}
|
||||
return await self._device._query_setter_helper(
|
||||
"setBCDConfig", self.QUERY_MODULE_NAME, "bcd", params
|
||||
)
|
@ -1,16 +1,18 @@
|
||||
"""Implementation of device module."""
|
||||
"""Implementation of camera module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import base64
|
||||
import logging
|
||||
from enum import StrEnum
|
||||
from typing import Annotated
|
||||
from urllib.parse import quote_plus
|
||||
|
||||
from ...credentials import Credentials
|
||||
from ...device_type import DeviceType
|
||||
from ...feature import Feature
|
||||
from ...json import loads as json_loads
|
||||
from ...module import FeatureAttribute, Module
|
||||
from ..smartcammodule import SmartCamModule
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
@ -29,28 +31,38 @@ class StreamResolution(StrEnum):
|
||||
class Camera(SmartCamModule):
|
||||
"""Implementation of device module."""
|
||||
|
||||
QUERY_GETTER_NAME = "getLensMaskConfig"
|
||||
QUERY_MODULE_NAME = "lens_mask"
|
||||
QUERY_SECTION_NAMES = "lens_mask_info"
|
||||
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
self._device,
|
||||
id="state",
|
||||
name="State",
|
||||
attribute_getter="is_on",
|
||||
attribute_setter="set_state",
|
||||
type=Feature.Type.Switch,
|
||||
category=Feature.Category.Primary,
|
||||
if Module.LensMask in self._device.modules:
|
||||
self._add_feature(
|
||||
Feature(
|
||||
self._device,
|
||||
id="state",
|
||||
name="State",
|
||||
container=self,
|
||||
attribute_getter="is_on",
|
||||
attribute_setter="set_state",
|
||||
type=Feature.Type.Switch,
|
||||
category=Feature.Category.Primary,
|
||||
)
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def is_on(self) -> bool:
|
||||
"""Return the device id."""
|
||||
return self.data["lens_mask_info"]["enabled"] == "off"
|
||||
"""Return the device on state."""
|
||||
if lens_mask := self._device.modules.get(Module.LensMask):
|
||||
return not lens_mask.enabled
|
||||
return True
|
||||
|
||||
async def set_state(self, on: bool) -> Annotated[dict, FeatureAttribute()]:
|
||||
"""Set the device on state.
|
||||
|
||||
If the device does not support setting state will do nothing.
|
||||
"""
|
||||
if lens_mask := self._device.modules.get(Module.LensMask):
|
||||
# Turning off enables the privacy mask which is why value is reversed.
|
||||
return await lens_mask.set_enabled(not on)
|
||||
return {}
|
||||
|
||||
def _get_credentials(self) -> Credentials | None:
|
||||
"""Get credentials from ."""
|
||||
@ -109,14 +121,6 @@ class Camera(SmartCamModule):
|
||||
"""Return the onvif url."""
|
||||
return f"http://{self._device.host}:{ONVIF_PORT}/onvif/device_service"
|
||||
|
||||
async def set_state(self, on: bool) -> dict:
|
||||
"""Set the device state."""
|
||||
# Turning off enables the privacy mask which is why value is reversed.
|
||||
params = {"enabled": "off" if on else "on"}
|
||||
return await self._device._query_setter_helper(
|
||||
"setLensMaskConfig", self.QUERY_MODULE_NAME, "lens_mask_info", params
|
||||
)
|
||||
|
||||
async def _check_supported(self) -> bool:
|
||||
"""Additional check to see if the module is supported by the device."""
|
||||
return self._device.device_type is DeviceType.Camera
|
||||
|
@ -14,6 +14,13 @@ class DeviceModule(SmartCamModule):
|
||||
QUERY_MODULE_NAME = "device_info"
|
||||
QUERY_SECTION_NAMES = ["basic_info", "info"]
|
||||
|
||||
def query(self) -> dict:
|
||||
"""Query to execute during the update cycle."""
|
||||
q = super().query()
|
||||
q["getConnectionType"] = {"network": {"get_connection_type": []}}
|
||||
|
||||
return q
|
||||
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
@ -26,6 +33,32 @@ class DeviceModule(SmartCamModule):
|
||||
type=Feature.Type.Sensor,
|
||||
)
|
||||
)
|
||||
if self.rssi is not None:
|
||||
self._add_feature(
|
||||
Feature(
|
||||
self._device,
|
||||
container=self,
|
||||
id="rssi",
|
||||
name="RSSI",
|
||||
attribute_getter="rssi",
|
||||
icon="mdi:signal",
|
||||
unit_getter=lambda: "dBm",
|
||||
category=Feature.Category.Debug,
|
||||
type=Feature.Type.Sensor,
|
||||
)
|
||||
)
|
||||
self._add_feature(
|
||||
Feature(
|
||||
self._device,
|
||||
container=self,
|
||||
id="signal_level",
|
||||
name="Signal Level",
|
||||
attribute_getter="signal_level",
|
||||
icon="mdi:signal",
|
||||
category=Feature.Category.Info,
|
||||
type=Feature.Type.Sensor,
|
||||
)
|
||||
)
|
||||
|
||||
async def _post_update_hook(self) -> None:
|
||||
"""Overriden to prevent module disabling.
|
||||
@ -37,4 +70,14 @@ class DeviceModule(SmartCamModule):
|
||||
@property
|
||||
def device_id(self) -> str:
|
||||
"""Return the device id."""
|
||||
return self.data["basic_info"]["dev_id"]
|
||||
return self.data[self.QUERY_GETTER_NAME]["basic_info"]["dev_id"]
|
||||
|
||||
@property
|
||||
def rssi(self) -> int | None:
|
||||
"""Return the device id."""
|
||||
return self.data["getConnectionType"].get("rssiValue")
|
||||
|
||||
@property
|
||||
def signal_level(self) -> int | None:
|
||||
"""Return the device id."""
|
||||
return self.data["getConnectionType"].get("rssi")
|
||||
|
31
kasa/smartcam/modules/lensmask.py
Normal file
31
kasa/smartcam/modules/lensmask.py
Normal file
@ -0,0 +1,31 @@
|
||||
"""Implementation of lens mask privacy module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from ..smartcammodule import SmartCamModule
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class LensMask(SmartCamModule):
|
||||
"""Implementation of lens mask module."""
|
||||
|
||||
REQUIRED_COMPONENT = "lensMask"
|
||||
|
||||
QUERY_GETTER_NAME = "getLensMaskConfig"
|
||||
QUERY_MODULE_NAME = "lens_mask"
|
||||
QUERY_SECTION_NAMES = "lens_mask_info"
|
||||
|
||||
@property
|
||||
def enabled(self) -> bool:
|
||||
"""Return the lens mask state."""
|
||||
return self.data["lens_mask_info"]["enabled"] == "on"
|
||||
|
||||
async def set_enabled(self, enable: bool) -> dict:
|
||||
"""Set the lens mask state."""
|
||||
params = {"enabled": "on" if enable else "off"}
|
||||
return await self._device._query_setter_helper(
|
||||
"setLensMaskConfig", self.QUERY_MODULE_NAME, "lens_mask_info", params
|
||||
)
|
47
kasa/smartcam/modules/motiondetection.py
Normal file
47
kasa/smartcam/modules/motiondetection.py
Normal file
@ -0,0 +1,47 @@
|
||||
"""Implementation of motion detection module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from ...feature import Feature
|
||||
from ..smartcammodule import SmartCamModule
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class MotionDetection(SmartCamModule):
|
||||
"""Implementation of motion detection module."""
|
||||
|
||||
REQUIRED_COMPONENT = "detection"
|
||||
|
||||
QUERY_GETTER_NAME = "getDetectionConfig"
|
||||
QUERY_MODULE_NAME = "motion_detection"
|
||||
QUERY_SECTION_NAMES = "motion_det"
|
||||
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
self._device,
|
||||
id="motion_detection",
|
||||
name="Motion detection",
|
||||
container=self,
|
||||
attribute_getter="enabled",
|
||||
attribute_setter="set_enabled",
|
||||
type=Feature.Type.Switch,
|
||||
category=Feature.Category.Primary,
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def enabled(self) -> bool:
|
||||
"""Return the motion detection enabled state."""
|
||||
return self.data["motion_det"]["enabled"] == "on"
|
||||
|
||||
async def set_enabled(self, enable: bool) -> dict:
|
||||
"""Set the motion detection enabled state."""
|
||||
params = {"enabled": "on" if enable else "off"}
|
||||
return await self._device._query_setter_helper(
|
||||
"setDetectionConfig", self.QUERY_MODULE_NAME, "motion_det", params
|
||||
)
|
47
kasa/smartcam/modules/persondetection.py
Normal file
47
kasa/smartcam/modules/persondetection.py
Normal file
@ -0,0 +1,47 @@
|
||||
"""Implementation of person detection module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from ...feature import Feature
|
||||
from ..smartcammodule import SmartCamModule
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class PersonDetection(SmartCamModule):
|
||||
"""Implementation of person detection module."""
|
||||
|
||||
REQUIRED_COMPONENT = "personDetection"
|
||||
|
||||
QUERY_GETTER_NAME = "getPersonDetectionConfig"
|
||||
QUERY_MODULE_NAME = "people_detection"
|
||||
QUERY_SECTION_NAMES = "detection"
|
||||
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
self._device,
|
||||
id="person_detection",
|
||||
name="Person detection",
|
||||
container=self,
|
||||
attribute_getter="enabled",
|
||||
attribute_setter="set_enabled",
|
||||
type=Feature.Type.Switch,
|
||||
category=Feature.Category.Primary,
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def enabled(self) -> bool:
|
||||
"""Return the person detection enabled state."""
|
||||
return self.data["detection"]["enabled"] == "on"
|
||||
|
||||
async def set_enabled(self, enable: bool) -> dict:
|
||||
"""Set the person detection enabled state."""
|
||||
params = {"enabled": "on" if enable else "off"}
|
||||
return await self._device._query_setter_helper(
|
||||
"setPersonDetectionConfig", self.QUERY_MODULE_NAME, "detection", params
|
||||
)
|
47
kasa/smartcam/modules/tamperdetection.py
Normal file
47
kasa/smartcam/modules/tamperdetection.py
Normal file
@ -0,0 +1,47 @@
|
||||
"""Implementation of tamper detection module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
import logging
|
||||
|
||||
from ...feature import Feature
|
||||
from ..smartcammodule import SmartCamModule
|
||||
|
||||
_LOGGER = logging.getLogger(__name__)
|
||||
|
||||
|
||||
class TamperDetection(SmartCamModule):
|
||||
"""Implementation of tamper detection module."""
|
||||
|
||||
REQUIRED_COMPONENT = "tamperDetection"
|
||||
|
||||
QUERY_GETTER_NAME = "getTamperDetectionConfig"
|
||||
QUERY_MODULE_NAME = "tamper_detection"
|
||||
QUERY_SECTION_NAMES = "tamper_det"
|
||||
|
||||
def _initialize_features(self) -> None:
|
||||
"""Initialize features after the initial update."""
|
||||
self._add_feature(
|
||||
Feature(
|
||||
self._device,
|
||||
id="tamper_detection",
|
||||
name="Tamper detection",
|
||||
container=self,
|
||||
attribute_getter="enabled",
|
||||
attribute_setter="set_enabled",
|
||||
type=Feature.Type.Switch,
|
||||
category=Feature.Category.Primary,
|
||||
)
|
||||
)
|
||||
|
||||
@property
|
||||
def enabled(self) -> bool:
|
||||
"""Return the tamper detection enabled state."""
|
||||
return self.data["tamper_det"]["enabled"] == "on"
|
||||
|
||||
async def set_enabled(self, enable: bool) -> dict:
|
||||
"""Set the tamper detection enabled state."""
|
||||
params = {"enabled": "on" if enable else "off"}
|
||||
return await self._device._query_setter_helper(
|
||||
"setTamperDetectionConfig", self.QUERY_MODULE_NAME, "tamper_det", params
|
||||
)
|
@ -134,6 +134,11 @@ class SmartCamDevice(SmartDevice):
|
||||
if (
|
||||
mod.REQUIRED_COMPONENT
|
||||
and mod.REQUIRED_COMPONENT not in self._components
|
||||
# Always add Camera module to cameras
|
||||
and (
|
||||
mod._module_name() != Module.Camera
|
||||
or self._device_type is not DeviceType.Camera
|
||||
)
|
||||
):
|
||||
continue
|
||||
module = mod(self, mod._module_name())
|
||||
@ -180,6 +185,7 @@ class SmartCamDevice(SmartDevice):
|
||||
initial_query = {
|
||||
"getDeviceInfo": {"device_info": {"name": ["basic_info", "info"]}},
|
||||
"getAppComponentList": {"app_component": {"name": "app_component_list"}},
|
||||
"getConnectionType": {"network": {"get_connection_type": {}}},
|
||||
}
|
||||
resp = await self.protocol.query(initial_query)
|
||||
self._last_update.update(resp)
|
||||
@ -256,3 +262,8 @@ class SmartCamDevice(SmartDevice):
|
||||
"dev_name": self.alias,
|
||||
"oemId": self._info.get("oem_id"),
|
||||
}
|
||||
|
||||
@property
|
||||
def rssi(self) -> int | None:
|
||||
"""Return the device id."""
|
||||
return self.modules[SmartCamModule.SmartCamDeviceModule].rssi
|
||||
|
@ -20,6 +20,22 @@ class SmartCamModule(SmartModule):
|
||||
"""Base class for SMARTCAM modules."""
|
||||
|
||||
SmartCamAlarm: Final[ModuleName[modules.Alarm]] = ModuleName("SmartCamAlarm")
|
||||
SmartCamMotionDetection: Final[ModuleName[modules.MotionDetection]] = ModuleName(
|
||||
"MotionDetection"
|
||||
)
|
||||
SmartCamPersonDetection: Final[ModuleName[modules.PersonDetection]] = ModuleName(
|
||||
"PersonDetection"
|
||||
)
|
||||
SmartCamTamperDetection: Final[ModuleName[modules.TamperDetection]] = ModuleName(
|
||||
"TamperDetection"
|
||||
)
|
||||
SmartCamBabyCryDetection: Final[ModuleName[modules.BabyCryDetection]] = ModuleName(
|
||||
"BabyCryDetection"
|
||||
)
|
||||
|
||||
SmartCamDeviceModule: Final[ModuleName[modules.DeviceModule]] = ModuleName(
|
||||
"devicemodule"
|
||||
)
|
||||
|
||||
#: Module name to be queried
|
||||
QUERY_MODULE_NAME: str
|
||||
|
@ -8,6 +8,7 @@ import hashlib
|
||||
import logging
|
||||
import secrets
|
||||
import ssl
|
||||
from contextlib import suppress
|
||||
from enum import Enum, auto
|
||||
from typing import TYPE_CHECKING, Any, cast
|
||||
|
||||
@ -160,6 +161,19 @@ class SslAesTransport(BaseTransport):
|
||||
error_code = SmartErrorCode.INTERNAL_UNKNOWN_ERROR
|
||||
return error_code
|
||||
|
||||
def _get_response_inner_error(self, resp_dict: Any) -> SmartErrorCode | None:
|
||||
error_code_raw = resp_dict.get("data", {}).get("code")
|
||||
if error_code_raw is None:
|
||||
return None
|
||||
try:
|
||||
error_code = SmartErrorCode.from_int(error_code_raw)
|
||||
except ValueError:
|
||||
_LOGGER.warning(
|
||||
"Device %s received unknown error code: %s", self._host, error_code_raw
|
||||
)
|
||||
error_code = SmartErrorCode.INTERNAL_UNKNOWN_ERROR
|
||||
return error_code
|
||||
|
||||
def _handle_response_error_code(self, resp_dict: Any, msg: str) -> None:
|
||||
error_code = self._get_response_error(resp_dict)
|
||||
if error_code is SmartErrorCode.SUCCESS:
|
||||
@ -216,6 +230,31 @@ class SslAesTransport(BaseTransport):
|
||||
ssl=await self._get_ssl_context(),
|
||||
)
|
||||
|
||||
if TYPE_CHECKING:
|
||||
assert self._encryption_session is not None
|
||||
|
||||
# Devices can respond with 500 if another session is created from
|
||||
# the same host. Decryption may not succeed after that
|
||||
if status_code == 500:
|
||||
msg = (
|
||||
f"Device {self._host} replied with status 500 after handshake, "
|
||||
f"response: "
|
||||
)
|
||||
decrypted = None
|
||||
if isinstance(resp_dict, dict) and (
|
||||
response := resp_dict.get("result", {}).get("response")
|
||||
):
|
||||
with suppress(Exception):
|
||||
decrypted = self._encryption_session.decrypt(response.encode())
|
||||
|
||||
if decrypted:
|
||||
msg += decrypted
|
||||
else:
|
||||
msg += str(resp_dict)
|
||||
|
||||
_LOGGER.debug(msg)
|
||||
raise _RetryableError(msg)
|
||||
|
||||
if status_code != 200:
|
||||
raise KasaException(
|
||||
f"{self._host} responded with an unexpected "
|
||||
@ -228,7 +267,6 @@ class SslAesTransport(BaseTransport):
|
||||
|
||||
if TYPE_CHECKING:
|
||||
resp_dict = cast(dict[str, Any], resp_dict)
|
||||
assert self._encryption_session is not None
|
||||
|
||||
if "result" in resp_dict and "response" in resp_dict["result"]:
|
||||
raw_response: str = resp_dict["result"]["response"]
|
||||
@ -383,13 +421,29 @@ class SslAesTransport(BaseTransport):
|
||||
error_code = default_error_code
|
||||
resp_dict = default_resp_dict
|
||||
|
||||
# If the default login worked it's ok not to provide credentials but if
|
||||
# it didn't raise auth error here.
|
||||
if not self._username:
|
||||
raise AuthenticationError(
|
||||
f"Credentials must be supplied to connect to {self._host}"
|
||||
)
|
||||
|
||||
# Device responds with INVALID_NONCE and a "nonce" to indicate ready
|
||||
# for secure login. Otherwise error.
|
||||
if error_code is not SmartErrorCode.INVALID_NONCE or (
|
||||
resp_dict and "nonce" not in resp_dict["result"].get("data", {})
|
||||
resp_dict and "nonce" not in resp_dict.get("result", {}).get("data", {})
|
||||
):
|
||||
if (
|
||||
resp_dict
|
||||
and self._get_response_inner_error(resp_dict)
|
||||
is SmartErrorCode.DEVICE_BLOCKED
|
||||
):
|
||||
sec_left = resp_dict.get("data", {}).get("sec_left")
|
||||
msg = "Device blocked" + (
|
||||
f" for {sec_left} seconds" if sec_left else ""
|
||||
)
|
||||
raise DeviceError(msg, error_code=SmartErrorCode.DEVICE_BLOCKED)
|
||||
|
||||
raise AuthenticationError(f"Error trying handshake1: {resp_dict}")
|
||||
|
||||
if TYPE_CHECKING:
|
||||
|
@ -1,6 +1,6 @@
|
||||
[project]
|
||||
name = "python-kasa"
|
||||
version = "0.8.1"
|
||||
version = "0.9.0"
|
||||
description = "Python API for TP-Link Kasa and Tapo devices"
|
||||
license = {text = "GPL-3.0-or-later"}
|
||||
authors = [ { name = "python-kasa developers" }]
|
||||
|
@ -79,8 +79,6 @@ PLUGS_IOT = {
|
||||
"KP125",
|
||||
"KP401",
|
||||
}
|
||||
# P135 supports dimming, but its not currently support
|
||||
# by the library
|
||||
PLUGS_SMART = {
|
||||
"P100",
|
||||
"P110",
|
||||
@ -112,7 +110,7 @@ SWITCHES_SMART = {
|
||||
}
|
||||
SWITCHES = {*SWITCHES_IOT, *SWITCHES_SMART}
|
||||
STRIPS_IOT = {"HS107", "HS300", "KP303", "KP200", "KP400", "EP40"}
|
||||
STRIPS_SMART = {"P300", "P304M", "TP25", "EP40M"}
|
||||
STRIPS_SMART = {"P300", "P304M", "TP25", "EP40M", "P210M", "P306"}
|
||||
STRIPS = {*STRIPS_IOT, *STRIPS_SMART}
|
||||
|
||||
DIMMERS_IOT = {"ES20M", "HS220", "KS220", "KS220M", "KS230", "KP405"}
|
||||
|
@ -160,6 +160,17 @@ def create_discovery_mock(ip: str, fixture_data: dict):
|
||||
login_version: int | None = None
|
||||
port_override: int | None = None
|
||||
|
||||
@property
|
||||
def model(self) -> str:
|
||||
dd = self.discovery_data
|
||||
model_region = (
|
||||
dd["result"]["device_model"]
|
||||
if self.discovery_port == 20002
|
||||
else dd["system"]["get_sysinfo"]["model"]
|
||||
)
|
||||
model, _, _ = model_region.partition("(")
|
||||
return model
|
||||
|
||||
@property
|
||||
def _datagram(self) -> bytes:
|
||||
if self.default_port == 9999:
|
||||
@ -178,7 +189,10 @@ def create_discovery_mock(ip: str, fixture_data: dict):
|
||||
"encrypt_type", discovery_result.get("encrypt_info", {}).get("sym_schm")
|
||||
)
|
||||
|
||||
login_version = discovery_result["mgt_encrypt_schm"].get("lv")
|
||||
if not (login_version := discovery_result["mgt_encrypt_schm"].get("lv")) and (
|
||||
et := discovery_result.get("encrypt_type")
|
||||
):
|
||||
login_version = max([int(i) for i in et])
|
||||
https = discovery_result["mgt_encrypt_schm"]["is_support_https"]
|
||||
dm = _DiscoveryMock(
|
||||
ip,
|
||||
|
419
tests/fixtures/smart/P135(US)_1.0_1.2.0.json
vendored
Normal file
419
tests/fixtures/smart/P135(US)_1.0_1.2.0.json
vendored
Normal file
@ -0,0 +1,419 @@
|
||||
{
|
||||
"component_nego": {
|
||||
"component_list": [
|
||||
{
|
||||
"id": "device",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "firmware",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "quick_setup",
|
||||
"ver_code": 3
|
||||
},
|
||||
{
|
||||
"id": "inherit",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "time",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "wireless",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "schedule",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "countdown",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "antitheft",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "account",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "synchronize",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "sunrise_sunset",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "led",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "cloud_connect",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "iot_cloud",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "device_local_time",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "default_states",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "brightness",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "preset",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "on_off_gradually",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "dimmer_calibration",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "localSmart",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "overheat_protection",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "matter",
|
||||
"ver_code": 2
|
||||
}
|
||||
]
|
||||
},
|
||||
"discovery_result": {
|
||||
"error_code": 0,
|
||||
"result": {
|
||||
"device_id": "00000000000000000000000000000000",
|
||||
"device_model": "P135(US)",
|
||||
"device_type": "SMART.TAPOPLUG",
|
||||
"factory_default": false,
|
||||
"ip": "127.0.0.123",
|
||||
"is_support_iot_cloud": true,
|
||||
"mac": "F0-09-0D-00-00-00",
|
||||
"mgt_encrypt_schm": {
|
||||
"encrypt_type": "KLAP",
|
||||
"http_port": 80,
|
||||
"is_support_https": false,
|
||||
"lv": 2
|
||||
},
|
||||
"obd_src": "tplink",
|
||||
"owner": "00000000000000000000000000000000",
|
||||
"protocol_version": 1
|
||||
}
|
||||
},
|
||||
"get_antitheft_rules": {
|
||||
"antitheft_rule_max_count": 1,
|
||||
"enable": false,
|
||||
"rule_list": []
|
||||
},
|
||||
"get_auto_update_info": {
|
||||
"enable": true,
|
||||
"random_range": 120,
|
||||
"time": 180
|
||||
},
|
||||
"get_connect_cloud_state": {
|
||||
"status": 0
|
||||
},
|
||||
"get_countdown_rules": {
|
||||
"countdown_rule_max_count": 1,
|
||||
"enable": false,
|
||||
"rule_list": []
|
||||
},
|
||||
"get_device_info": {
|
||||
"accessory_at_low_battery": false,
|
||||
"avatar": "plug",
|
||||
"brightness": 100,
|
||||
"default_states": {
|
||||
"re_power_type": "always_off",
|
||||
"re_power_type_capability": [
|
||||
"last_states",
|
||||
"always_on",
|
||||
"always_off"
|
||||
],
|
||||
"type": "last_states"
|
||||
},
|
||||
"device_id": "0000000000000000000000000000000000000000",
|
||||
"device_on": true,
|
||||
"fw_id": "00000000000000000000000000000000",
|
||||
"fw_ver": "1.2.0 Build 240415 Rel.171222",
|
||||
"has_set_location_info": false,
|
||||
"hw_id": "00000000000000000000000000000000",
|
||||
"hw_ver": "1.0",
|
||||
"ip": "127.0.0.123",
|
||||
"lang": "",
|
||||
"latitude": 0,
|
||||
"longitude": 0,
|
||||
"mac": "F0-09-0D-00-00-00",
|
||||
"model": "P135",
|
||||
"nickname": "I01BU0tFRF9OQU1FIw==",
|
||||
"oem_id": "00000000000000000000000000000000",
|
||||
"on_time": 3428,
|
||||
"overheat_status": "normal",
|
||||
"region": "America/Los_Angeles",
|
||||
"rssi": -35,
|
||||
"signal_level": 3,
|
||||
"specs": "",
|
||||
"ssid": "I01BU0tFRF9TU0lEIw==",
|
||||
"time_diff": -480,
|
||||
"type": "SMART.TAPOPLUG"
|
||||
},
|
||||
"get_device_time": {
|
||||
"region": "America/Los_Angeles",
|
||||
"time_diff": -480,
|
||||
"timestamp": 1734735856
|
||||
},
|
||||
"get_device_usage": {
|
||||
"time_usage": {
|
||||
"past30": 57,
|
||||
"past7": 57,
|
||||
"today": 57
|
||||
}
|
||||
},
|
||||
"get_fw_download_state": {
|
||||
"auto_upgrade": false,
|
||||
"download_progress": 0,
|
||||
"reboot_time": 5,
|
||||
"status": 0,
|
||||
"upgrade_time": 5
|
||||
},
|
||||
"get_inherit_info": null,
|
||||
"get_latest_fw": {
|
||||
"fw_size": 0,
|
||||
"fw_ver": "1.2.0 Build 240415 Rel.171222",
|
||||
"hw_id": "",
|
||||
"need_to_upgrade": false,
|
||||
"oem_id": "",
|
||||
"release_date": "",
|
||||
"release_note": "",
|
||||
"type": 0
|
||||
},
|
||||
"get_led_info": {
|
||||
"bri_config": {
|
||||
"bri_type": "overall",
|
||||
"overall_bri": 50
|
||||
},
|
||||
"led_rule": "always",
|
||||
"led_status": true,
|
||||
"night_mode": {
|
||||
"end_time": 420,
|
||||
"night_mode_type": "custom",
|
||||
"start_time": 1320
|
||||
}
|
||||
},
|
||||
"get_matter_setup_info": {
|
||||
"setup_code": "00000000000",
|
||||
"setup_payload": "00:0000000000000000000"
|
||||
},
|
||||
"get_next_event": {},
|
||||
"get_on_off_gradually_info": {
|
||||
"off_state": {
|
||||
"duration": 1,
|
||||
"enable": true,
|
||||
"max_duration": 60
|
||||
},
|
||||
"on_state": {
|
||||
"duration": 1,
|
||||
"enable": true,
|
||||
"max_duration": 60
|
||||
}
|
||||
},
|
||||
"get_preset_rules": {
|
||||
"brightness": [
|
||||
100,
|
||||
75,
|
||||
50,
|
||||
25,
|
||||
1
|
||||
]
|
||||
},
|
||||
"get_schedule_rules": {
|
||||
"enable": false,
|
||||
"rule_list": [],
|
||||
"schedule_rule_max_count": 32,
|
||||
"start_index": 0,
|
||||
"sum": 0
|
||||
},
|
||||
"get_wireless_scan_info": {
|
||||
"ap_list": [
|
||||
{
|
||||
"bssid": "000000000000",
|
||||
"channel": 0,
|
||||
"cipher_type": 2,
|
||||
"key_type": "wpa2_psk",
|
||||
"signal_level": 3,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"bssid": "000000000000",
|
||||
"channel": 0,
|
||||
"cipher_type": 2,
|
||||
"key_type": "wpa2_psk",
|
||||
"signal_level": 3,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"bssid": "000000000000",
|
||||
"channel": 0,
|
||||
"cipher_type": 2,
|
||||
"key_type": "wpa2_psk",
|
||||
"signal_level": 3,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"bssid": "000000000000",
|
||||
"channel": 0,
|
||||
"cipher_type": 2,
|
||||
"key_type": "wpa2_psk",
|
||||
"signal_level": 3,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"bssid": "000000000000",
|
||||
"channel": 0,
|
||||
"cipher_type": 2,
|
||||
"key_type": "wpa2_psk",
|
||||
"signal_level": 2,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"bssid": "000000000000",
|
||||
"channel": 0,
|
||||
"cipher_type": 2,
|
||||
"key_type": "wpa2_psk",
|
||||
"signal_level": 2,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"bssid": "000000000000",
|
||||
"channel": 0,
|
||||
"cipher_type": 2,
|
||||
"key_type": "wpa2_psk",
|
||||
"signal_level": 2,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"bssid": "000000000000",
|
||||
"channel": 0,
|
||||
"cipher_type": 2,
|
||||
"key_type": "wpa2_psk",
|
||||
"signal_level": 2,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"bssid": "000000000000",
|
||||
"channel": 0,
|
||||
"cipher_type": 2,
|
||||
"key_type": "wpa2_psk",
|
||||
"signal_level": 2,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"bssid": "000000000000",
|
||||
"channel": 0,
|
||||
"cipher_type": 2,
|
||||
"key_type": "wpa2_psk",
|
||||
"signal_level": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"bssid": "000000000000",
|
||||
"channel": 0,
|
||||
"cipher_type": 2,
|
||||
"key_type": "wpa2_psk",
|
||||
"signal_level": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"bssid": "000000000000",
|
||||
"channel": 0,
|
||||
"cipher_type": 2,
|
||||
"key_type": "wpa2_psk",
|
||||
"signal_level": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"bssid": "000000000000",
|
||||
"channel": 0,
|
||||
"cipher_type": 2,
|
||||
"key_type": "wpa2_psk",
|
||||
"signal_level": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"bssid": "000000000000",
|
||||
"channel": 0,
|
||||
"cipher_type": 2,
|
||||
"key_type": "wpa2_psk",
|
||||
"signal_level": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"bssid": "000000000000",
|
||||
"channel": 0,
|
||||
"cipher_type": 2,
|
||||
"key_type": "wpa2_psk",
|
||||
"signal_level": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
}
|
||||
],
|
||||
"start_index": 0,
|
||||
"sum": 15,
|
||||
"wep_supported": false
|
||||
},
|
||||
"qs_component_nego": {
|
||||
"component_list": [
|
||||
{
|
||||
"id": "quick_setup",
|
||||
"ver_code": 3
|
||||
},
|
||||
{
|
||||
"id": "sunrise_sunset",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "ble_whole_setup",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "matter",
|
||||
"ver_code": 2
|
||||
},
|
||||
{
|
||||
"id": "iot_cloud",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "inherit",
|
||||
"ver_code": 1
|
||||
},
|
||||
{
|
||||
"id": "firmware",
|
||||
"ver_code": 2
|
||||
}
|
||||
],
|
||||
"extra_info": {
|
||||
"device_model": "P135",
|
||||
"device_type": "SMART.TAPOPLUG",
|
||||
"is_klap": true
|
||||
}
|
||||
}
|
||||
}
|
1585
tests/fixtures/smart/P210M(US)_1.0_1.0.3.json
vendored
Normal file
1585
tests/fixtures/smart/P210M(US)_1.0_1.0.3.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1708
tests/fixtures/smart/P306(US)_1.0_1.1.2.json
vendored
Normal file
1708
tests/fixtures/smart/P306(US)_1.0_1.1.2.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
779
tests/fixtures/smartcam/C100_4.0_1.3.14.json
vendored
Normal file
779
tests/fixtures/smartcam/C100_4.0_1.3.14.json
vendored
Normal file
@ -0,0 +1,779 @@
|
||||
{
|
||||
"discovery_result": {
|
||||
"error_code": 0,
|
||||
"result": {
|
||||
"decrypted_data": {
|
||||
"connect_ssid": "#MASKED_SSID#",
|
||||
"connect_type": "wireless",
|
||||
"device_id": "0000000000000000000000000000000000000000",
|
||||
"http_port": 443,
|
||||
"owner": "00000000000000000000000000000000",
|
||||
"sd_status": "offline"
|
||||
},
|
||||
"device_id": "00000000000000000000000000000000",
|
||||
"device_model": "C100",
|
||||
"device_name": "#MASKED_NAME#",
|
||||
"device_type": "SMART.IPCAMERA",
|
||||
"encrypt_info": {
|
||||
"data": "",
|
||||
"key": "",
|
||||
"sym_schm": "AES"
|
||||
},
|
||||
"encrypt_type": [
|
||||
"3"
|
||||
],
|
||||
"factory_default": false,
|
||||
"firmware_version": "1.3.14 Build 240513 Rel.43631n(5553)",
|
||||
"hardware_version": "4.0",
|
||||
"ip": "127.0.0.123",
|
||||
"is_support_iot_cloud": true,
|
||||
"mac": "F0-A7-31-00-00-00",
|
||||
"mgt_encrypt_schm": {
|
||||
"is_support_https": true
|
||||
},
|
||||
"protocol_version": 1
|
||||
}
|
||||
},
|
||||
"getAlertPlan": {
|
||||
"msg_alarm_plan": {
|
||||
"chn1_msg_alarm_plan": {
|
||||
".name": "chn1_msg_alarm_plan",
|
||||
".type": "plan",
|
||||
"alarm_plan_1": "0000-0000,127",
|
||||
"enabled": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getAppComponentList": {
|
||||
"app_component": {
|
||||
"app_component_list": [
|
||||
{
|
||||
"name": "sdCard",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "timezone",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "system",
|
||||
"version": 3
|
||||
},
|
||||
{
|
||||
"name": "led",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "playback",
|
||||
"version": 4
|
||||
},
|
||||
{
|
||||
"name": "detection",
|
||||
"version": 3
|
||||
},
|
||||
{
|
||||
"name": "alert",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "firmware",
|
||||
"version": 2
|
||||
},
|
||||
{
|
||||
"name": "account",
|
||||
"version": 2
|
||||
},
|
||||
{
|
||||
"name": "quickSetup",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "video",
|
||||
"version": 2
|
||||
},
|
||||
{
|
||||
"name": "lensMask",
|
||||
"version": 2
|
||||
},
|
||||
{
|
||||
"name": "lightFrequency",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "dayNightMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "osd",
|
||||
"version": 2
|
||||
},
|
||||
{
|
||||
"name": "record",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "videoRotation",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "audio",
|
||||
"version": 2
|
||||
},
|
||||
{
|
||||
"name": "diagnose",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "msgPush",
|
||||
"version": 3
|
||||
},
|
||||
{
|
||||
"name": "deviceShare",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "tapoCare",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "blockZone",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "personDetection",
|
||||
"version": 2
|
||||
},
|
||||
{
|
||||
"name": "babyCryDetection",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "needSubscriptionServiceList",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "iotCloud",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "recordDownload",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "detectionRegion",
|
||||
"version": 2
|
||||
},
|
||||
{
|
||||
"name": "staticIp",
|
||||
"version": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"getAudioConfig": {
|
||||
"audio_config": {
|
||||
"microphone": {
|
||||
".name": "microphone",
|
||||
".type": "audio_config",
|
||||
"channels": "1",
|
||||
"encode_type": "G711alaw",
|
||||
"mute": "off",
|
||||
"noise_cancelling": "on",
|
||||
"sampling_rate": "8",
|
||||
"volume": "100"
|
||||
},
|
||||
"speaker": {
|
||||
".name": "speaker",
|
||||
".type": "audio_config",
|
||||
"volume": "40"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getBCDConfig": {
|
||||
"sound_detection": {
|
||||
"bcd": {
|
||||
".name": "bcd",
|
||||
".type": "on_off",
|
||||
"digital_sensitivity": "50",
|
||||
"enabled": "off",
|
||||
"sensitivity": "medium"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getCircularRecordingConfig": {
|
||||
"harddisk_manage": {
|
||||
"harddisk": {
|
||||
".name": "harddisk",
|
||||
".type": "storage",
|
||||
"loop": "on"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getClockStatus": {
|
||||
"system": {
|
||||
"clock_status": {
|
||||
"local_time": "2024-12-15 11:11:55",
|
||||
"seconds_from_1970": 1734279115
|
||||
}
|
||||
}
|
||||
},
|
||||
"getConnectionType": {
|
||||
"link_type": "wifi",
|
||||
"rssi": "4",
|
||||
"rssiValue": -15,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
"getDetectionConfig": {
|
||||
"motion_detection": {
|
||||
"motion_det": {
|
||||
".name": "motion_det",
|
||||
".type": "on_off",
|
||||
"digital_sensitivity": "50",
|
||||
"enabled": "off",
|
||||
"sensitivity": "medium"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getDeviceInfo": {
|
||||
"device_info": {
|
||||
"basic_info": {
|
||||
"avatar": "camera c100",
|
||||
"barcode": "",
|
||||
"dev_id": "0000000000000000000000000000000000000000",
|
||||
"device_alias": "#MASKED_NAME#",
|
||||
"device_info": "C100 4.0 IPC",
|
||||
"device_model": "C100",
|
||||
"device_name": "#MASKED_NAME#",
|
||||
"device_type": "SMART.IPCAMERA",
|
||||
"features": "3",
|
||||
"ffs": false,
|
||||
"has_set_location_info": 1,
|
||||
"hw_desc": "00000000000000000000000000000000",
|
||||
"hw_version": "4.0",
|
||||
"is_cal": true,
|
||||
"latitude": 0,
|
||||
"longitude": 0,
|
||||
"mac": "F0-A7-31-00-00-00",
|
||||
"oem_id": "00000000000000000000000000000000",
|
||||
"sw_version": "1.3.14 Build 240513 Rel.43631n(5553)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getFirmwareAutoUpgradeConfig": {
|
||||
"auto_upgrade": {
|
||||
"common": {
|
||||
".name": "common",
|
||||
".type": "on_off",
|
||||
"enabled": "off",
|
||||
"random_range": "120",
|
||||
"time": "03:00"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getFirmwareUpdateStatus": {
|
||||
"cloud_config": {
|
||||
"upgrade_status": {
|
||||
"lastUpgradingSuccess": true,
|
||||
"state": "normal"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getLastAlarmInfo": {
|
||||
"system": {
|
||||
"last_alarm_info": {
|
||||
"last_alarm_time": "",
|
||||
"last_alarm_type": ""
|
||||
}
|
||||
}
|
||||
},
|
||||
"getLdc": {
|
||||
"image": {
|
||||
"common": {
|
||||
".name": "common",
|
||||
".type": "para",
|
||||
"area_compensation": "default",
|
||||
"chroma": "50",
|
||||
"contrast": "50",
|
||||
"dehaze": "off",
|
||||
"exp_gain": "0",
|
||||
"exp_type": "auto",
|
||||
"focus_limited": "600",
|
||||
"focus_type": "semi_auto",
|
||||
"high_light_compensation": "off",
|
||||
"inf_delay": "10",
|
||||
"inf_end_time": "21600",
|
||||
"inf_sensitivity": "1",
|
||||
"inf_start_time": "64800",
|
||||
"inf_type": "auto",
|
||||
"light_freq_mode": "auto",
|
||||
"lock_blue_colton": "0",
|
||||
"lock_blue_gain": "0",
|
||||
"lock_gb_gain": "0",
|
||||
"lock_gr_gain": "0",
|
||||
"lock_green_colton": "0",
|
||||
"lock_red_colton": "0",
|
||||
"lock_red_gain": "0",
|
||||
"lock_source": "local",
|
||||
"luma": "50",
|
||||
"saturation": "50",
|
||||
"sharpness": "50",
|
||||
"shutter": "1/25",
|
||||
"smartir": "off",
|
||||
"smartir_level": "100",
|
||||
"wb_B_gain": "50",
|
||||
"wb_G_gain": "50",
|
||||
"wb_R_gain": "50",
|
||||
"wb_type": "auto",
|
||||
"wd_gain": "50",
|
||||
"wide_dynamic": "off"
|
||||
},
|
||||
"switch": {
|
||||
".name": "switch",
|
||||
".type": "switch_type",
|
||||
"flip_type": "off",
|
||||
"ldc": "off",
|
||||
"night_vision_mode": "inf_night_vision",
|
||||
"rotate_type": "off",
|
||||
"schedule_end_time": "64800",
|
||||
"schedule_start_time": "21600",
|
||||
"switch_mode": "common",
|
||||
"wtl_intensity_level": "5"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getLedStatus": {
|
||||
"led": {
|
||||
"config": {
|
||||
".name": "config",
|
||||
".type": "led",
|
||||
"enabled": "on"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getLensMaskConfig": {
|
||||
"lens_mask": {
|
||||
"lens_mask_info": {
|
||||
".name": "lens_mask_info",
|
||||
".type": "lens_mask_info",
|
||||
"enabled": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getLightFrequencyInfo": {
|
||||
"image": {
|
||||
"common": {
|
||||
".name": "common",
|
||||
".type": "para",
|
||||
"area_compensation": "default",
|
||||
"chroma": "50",
|
||||
"contrast": "50",
|
||||
"dehaze": "off",
|
||||
"exp_gain": "0",
|
||||
"exp_type": "auto",
|
||||
"focus_limited": "600",
|
||||
"focus_type": "semi_auto",
|
||||
"high_light_compensation": "off",
|
||||
"inf_delay": "10",
|
||||
"inf_end_time": "21600",
|
||||
"inf_sensitivity": "1",
|
||||
"inf_start_time": "64800",
|
||||
"inf_type": "auto",
|
||||
"light_freq_mode": "auto",
|
||||
"lock_blue_colton": "0",
|
||||
"lock_blue_gain": "0",
|
||||
"lock_gb_gain": "0",
|
||||
"lock_gr_gain": "0",
|
||||
"lock_green_colton": "0",
|
||||
"lock_red_colton": "0",
|
||||
"lock_red_gain": "0",
|
||||
"lock_source": "local",
|
||||
"luma": "50",
|
||||
"saturation": "50",
|
||||
"sharpness": "50",
|
||||
"shutter": "1/25",
|
||||
"smartir": "off",
|
||||
"smartir_level": "100",
|
||||
"wb_B_gain": "50",
|
||||
"wb_G_gain": "50",
|
||||
"wb_R_gain": "50",
|
||||
"wb_type": "auto",
|
||||
"wd_gain": "50",
|
||||
"wide_dynamic": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getMediaEncrypt": {
|
||||
"cet": {
|
||||
"media_encrypt": {
|
||||
".name": "media_encrypt",
|
||||
".type": "on_off",
|
||||
"enabled": "on"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getMsgPushConfig": {
|
||||
"msg_push": {
|
||||
"chn1_msg_push_info": {
|
||||
".name": "chn1_msg_push_info",
|
||||
".type": "on_off",
|
||||
"notification_enabled": "off",
|
||||
"rich_notification_enabled": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getNightVisionModeConfig": {
|
||||
"image": {
|
||||
"switch": {
|
||||
".name": "switch",
|
||||
".type": "switch_type",
|
||||
"flip_type": "off",
|
||||
"ldc": "off",
|
||||
"night_vision_mode": "inf_night_vision",
|
||||
"rotate_type": "off",
|
||||
"schedule_end_time": "64800",
|
||||
"schedule_start_time": "21600",
|
||||
"switch_mode": "common",
|
||||
"wtl_intensity_level": "5"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getPersonDetectionConfig": {
|
||||
"people_detection": {
|
||||
"detection": {
|
||||
".name": "detection",
|
||||
".type": "on_off",
|
||||
"enabled": "off",
|
||||
"sensitivity": "60"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getRecordPlan": {
|
||||
"record_plan": {
|
||||
"chn1_channel": {
|
||||
".name": "chn1_channel",
|
||||
".type": "plan",
|
||||
"enabled": "on",
|
||||
"friday": "[\"0000-2400:2\"]",
|
||||
"monday": "[\"0000-2400:2\"]",
|
||||
"saturday": "[\"0000-2400:2\"]",
|
||||
"sunday": "[\"0000-2400:2\"]",
|
||||
"thursday": "[\"0000-2400:2\"]",
|
||||
"tuesday": "[\"0000-2400:2\"]",
|
||||
"wednesday": "[\"0000-2400:2\"]"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getRotationStatus": {
|
||||
"image": {
|
||||
"switch": {
|
||||
".name": "switch",
|
||||
".type": "switch_type",
|
||||
"flip_type": "off",
|
||||
"ldc": "off",
|
||||
"night_vision_mode": "inf_night_vision",
|
||||
"rotate_type": "off",
|
||||
"schedule_end_time": "64800",
|
||||
"schedule_start_time": "21600",
|
||||
"switch_mode": "common",
|
||||
"wtl_intensity_level": "5"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getSdCardStatus": {
|
||||
"harddisk_manage": {
|
||||
"hd_info": [
|
||||
{
|
||||
"hd_info_1": {
|
||||
"detect_status": "offline",
|
||||
"disk_name": "1",
|
||||
"free_space": "0B",
|
||||
"loop_record_status": "0",
|
||||
"msg_push_free_space": "0B",
|
||||
"msg_push_total_space": "0B",
|
||||
"percent": "0",
|
||||
"picture_free_space": "0B",
|
||||
"picture_total_space": "0B",
|
||||
"record_duration": "0",
|
||||
"record_free_duration": "0",
|
||||
"record_start_time": "0",
|
||||
"rw_attr": "r",
|
||||
"status": "offline",
|
||||
"total_space": "0B",
|
||||
"type": "local",
|
||||
"video_free_space": "0B",
|
||||
"video_total_space": "0B",
|
||||
"write_protect": "0"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"getTamperDetectionConfig": {
|
||||
"tamper_detection": {
|
||||
"tamper_det": {
|
||||
".name": "tamper_det",
|
||||
".type": "on_off",
|
||||
"digital_sensitivity": "50",
|
||||
"enabled": "off",
|
||||
"sensitivity": "medium"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getTimezone": {
|
||||
"system": {
|
||||
"basic": {
|
||||
".name": "basic",
|
||||
".type": "setting",
|
||||
"timezone": "UTC-05:00",
|
||||
"timing_mode": "manual",
|
||||
"zone_id": "America/New_York"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getVideoCapability": {
|
||||
"video_capability": {
|
||||
"main": {
|
||||
".name": "main",
|
||||
".type": "capability",
|
||||
"bitrate_types": [
|
||||
"cbr",
|
||||
"vbr"
|
||||
],
|
||||
"bitrates": [
|
||||
"256",
|
||||
"512",
|
||||
"1024",
|
||||
"2048"
|
||||
],
|
||||
"encode_types": [
|
||||
"H264"
|
||||
],
|
||||
"frame_rates": [
|
||||
"65537",
|
||||
"65546",
|
||||
"65551"
|
||||
],
|
||||
"qualitys": [
|
||||
"1",
|
||||
"3",
|
||||
"5"
|
||||
],
|
||||
"resolutions": [
|
||||
"1920*1080",
|
||||
"1280*720",
|
||||
"640*360"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"getVideoQualities": {
|
||||
"video": {
|
||||
"main": {
|
||||
".name": "main",
|
||||
".type": "stream",
|
||||
"bitrate": "1024",
|
||||
"bitrate_type": "vbr",
|
||||
"encode_type": "H264",
|
||||
"frame_rate": "65551",
|
||||
"gop_factor": "2",
|
||||
"name": "VideoEncoder_1",
|
||||
"quality": "3",
|
||||
"resolution": "1920*1080",
|
||||
"stream_type": "general"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getWhitelampConfig": {
|
||||
"image": {
|
||||
"switch": {
|
||||
".name": "switch",
|
||||
".type": "switch_type",
|
||||
"flip_type": "off",
|
||||
"ldc": "off",
|
||||
"night_vision_mode": "inf_night_vision",
|
||||
"rotate_type": "off",
|
||||
"schedule_end_time": "64800",
|
||||
"schedule_start_time": "21600",
|
||||
"switch_mode": "common",
|
||||
"wtl_intensity_level": "5"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getWhitelampStatus": {
|
||||
"rest_time": 0,
|
||||
"status": 0
|
||||
},
|
||||
"get_audio_capability": {
|
||||
"get": {
|
||||
"audio_capability": {
|
||||
"device_microphone": {
|
||||
".name": "device_microphone",
|
||||
".type": "capability",
|
||||
"aec": "1",
|
||||
"channels": "1",
|
||||
"echo_cancelling": "0",
|
||||
"encode_type": [
|
||||
"G711alaw"
|
||||
],
|
||||
"half_duplex": "1",
|
||||
"mute": "1",
|
||||
"noise_cancelling": "1",
|
||||
"sampling_rate": [
|
||||
"8"
|
||||
],
|
||||
"volume": "1"
|
||||
},
|
||||
"device_speaker": {
|
||||
".name": "device_speaker",
|
||||
".type": "capability",
|
||||
"channels": "1",
|
||||
"decode_type": [
|
||||
"G711"
|
||||
],
|
||||
"mute": "0",
|
||||
"sampling_rate": [
|
||||
"8"
|
||||
],
|
||||
"volume": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"get_audio_config": {
|
||||
"get": {
|
||||
"audio_config": {
|
||||
"microphone": {
|
||||
".name": "microphone",
|
||||
".type": "audio_config",
|
||||
"channels": "1",
|
||||
"encode_type": "G711alaw",
|
||||
"mute": "off",
|
||||
"noise_cancelling": "on",
|
||||
"sampling_rate": "8",
|
||||
"volume": "100"
|
||||
},
|
||||
"speaker": {
|
||||
".name": "speaker",
|
||||
".type": "audio_config",
|
||||
"volume": "40"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"get_cet": {
|
||||
"get": {
|
||||
"cet": {
|
||||
"vhttpd": {
|
||||
".name": "vhttpd",
|
||||
".type": "server",
|
||||
"port": "8800"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"get_function": {
|
||||
"get": {
|
||||
"function": {
|
||||
"module_spec": {
|
||||
".name": "module_spec",
|
||||
".type": "module-spec",
|
||||
"ae_weighting_table_resolution": "5*5",
|
||||
"ai_enhance_capability": "1",
|
||||
"app_version": "1.0.0",
|
||||
"audio": [
|
||||
"speaker",
|
||||
"microphone"
|
||||
],
|
||||
"audioexception_detection": "0",
|
||||
"auth_encrypt": "1",
|
||||
"backlight_coexistence": "1",
|
||||
"change_password": "1",
|
||||
"client_info": "1",
|
||||
"cloud_storage_version": "1.0",
|
||||
"custom_area_compensation": "1",
|
||||
"custom_auto_mode_exposure_level": "0",
|
||||
"device_share": [
|
||||
"preview",
|
||||
"playback",
|
||||
"voice",
|
||||
"cloud_storage"
|
||||
],
|
||||
"download": [
|
||||
"video"
|
||||
],
|
||||
"events": [
|
||||
"motion",
|
||||
"tamper"
|
||||
],
|
||||
"greeter": "1.0",
|
||||
"http_system_state_audio_support": "1",
|
||||
"intrusion_detection": "1",
|
||||
"led": "1",
|
||||
"lens_mask": "1",
|
||||
"linecrossing_detection": "1",
|
||||
"linkage_capability": "1",
|
||||
"local_storage": "1",
|
||||
"media_encrypt": "1",
|
||||
"msg_alarm": "1",
|
||||
"msg_alarm_list": [
|
||||
"sound",
|
||||
"light"
|
||||
],
|
||||
"msg_alarm_separate_list": [
|
||||
"light",
|
||||
"sound"
|
||||
],
|
||||
"msg_push": "1",
|
||||
"multi_user": "0",
|
||||
"multicast": "0",
|
||||
"network": [
|
||||
"wifi"
|
||||
],
|
||||
"ota_upgrade": "1",
|
||||
"p2p_support_versions": [
|
||||
"1.1"
|
||||
],
|
||||
"playback": [
|
||||
"local",
|
||||
"p2p",
|
||||
"relay"
|
||||
],
|
||||
"playback_scale": "1",
|
||||
"preview": [
|
||||
"local",
|
||||
"p2p",
|
||||
"relay"
|
||||
],
|
||||
"privacy_mask_api_version": "1.0",
|
||||
"record_max_slot_cnt": "10",
|
||||
"record_type": [
|
||||
"timing",
|
||||
"motion"
|
||||
],
|
||||
"relay_support_versions": [
|
||||
"1.3"
|
||||
],
|
||||
"reonboarding": "1",
|
||||
"smart_detection": "1",
|
||||
"smart_msg_push_capability": "1",
|
||||
"ssl_cer_version": "1.0",
|
||||
"storage_api_version": "2.2",
|
||||
"stream_max_sessions": "10",
|
||||
"streaming_support_versions": [
|
||||
"1.0"
|
||||
],
|
||||
"target_track": "0",
|
||||
"timing_reboot": "1",
|
||||
"verification_change_password": "1",
|
||||
"video_codec": [
|
||||
"h264"
|
||||
],
|
||||
"video_detection_digital_sensitivity": "1",
|
||||
"wifi_cascade_connection": "1",
|
||||
"wifi_connection_info": "1",
|
||||
"wireless_hotspot": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
1283
tests/fixtures/smartcam/C225(US)_2.0_1.0.11.json
vendored
Normal file
1283
tests/fixtures/smartcam/C225(US)_2.0_1.0.11.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
1065
tests/fixtures/smartcam/C325WB(EU)_1.0_1.1.17.json
vendored
Normal file
1065
tests/fixtures/smartcam/C325WB(EU)_1.0_1.1.17.json
vendored
Normal file
File diff suppressed because it is too large
Load Diff
135
tests/fixtures/smartcam/C520WS(US)_1.0_1.2.8.json
vendored
135
tests/fixtures/smartcam/C520WS(US)_1.0_1.2.8.json
vendored
@ -7,8 +7,8 @@
|
||||
"connect_type": "wireless",
|
||||
"device_id": "0000000000000000000000000000000000000000",
|
||||
"http_port": 443,
|
||||
"last_alarm_time": "0",
|
||||
"last_alarm_type": "",
|
||||
"last_alarm_time": "1734386954",
|
||||
"last_alarm_type": "motion",
|
||||
"owner": "00000000000000000000000000000000",
|
||||
"sd_status": "offline"
|
||||
},
|
||||
@ -283,15 +283,22 @@
|
||||
"getClockStatus": {
|
||||
"system": {
|
||||
"clock_status": {
|
||||
"local_time": "2024-12-02 13:12:15",
|
||||
"seconds_from_1970": 1733163135
|
||||
"local_time": "2024-12-16 17:09:43",
|
||||
"seconds_from_1970": 1734386983
|
||||
}
|
||||
}
|
||||
},
|
||||
"getConnectStatus": {
|
||||
"onboarding": {
|
||||
"get_connect_status": {
|
||||
"status": 0
|
||||
}
|
||||
}
|
||||
},
|
||||
"getConnectionType": {
|
||||
"link_type": "wifi",
|
||||
"rssi": "4",
|
||||
"rssiValue": -47,
|
||||
"rssiValue": -45,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
"getDetectionConfig": {
|
||||
@ -355,8 +362,8 @@
|
||||
"getLastAlarmInfo": {
|
||||
"system": {
|
||||
"last_alarm_info": {
|
||||
"last_alarm_time": "0",
|
||||
"last_alarm_type": ""
|
||||
"last_alarm_time": "1734386954",
|
||||
"last_alarm_type": "motion"
|
||||
}
|
||||
}
|
||||
},
|
||||
@ -1025,5 +1032,119 @@
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"scanApList": {
|
||||
"onboarding": {
|
||||
"scan": {
|
||||
"ap_list": [
|
||||
{
|
||||
"auth": 3,
|
||||
"bssid": "000000000000",
|
||||
"encryption": 2,
|
||||
"rssi": 2,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"auth": 3,
|
||||
"bssid": "000000000000",
|
||||
"encryption": 2,
|
||||
"rssi": 2,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"auth": 3,
|
||||
"bssid": "000000000000",
|
||||
"encryption": 2,
|
||||
"rssi": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"auth": 3,
|
||||
"bssid": "000000000000",
|
||||
"encryption": 2,
|
||||
"rssi": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"auth": 3,
|
||||
"bssid": "000000000000",
|
||||
"encryption": 2,
|
||||
"rssi": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"auth": 3,
|
||||
"bssid": "000000000000",
|
||||
"encryption": 2,
|
||||
"rssi": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"auth": 3,
|
||||
"bssid": "000000000000",
|
||||
"encryption": 2,
|
||||
"rssi": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"auth": 3,
|
||||
"bssid": "000000000000",
|
||||
"encryption": 2,
|
||||
"rssi": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"auth": 3,
|
||||
"bssid": "000000000000",
|
||||
"encryption": 2,
|
||||
"rssi": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"auth": 3,
|
||||
"bssid": "000000000000",
|
||||
"encryption": 2,
|
||||
"rssi": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"auth": 3,
|
||||
"bssid": "000000000000",
|
||||
"encryption": 2,
|
||||
"rssi": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"auth": 3,
|
||||
"bssid": "000000000000",
|
||||
"encryption": 2,
|
||||
"rssi": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"auth": 3,
|
||||
"bssid": "000000000000",
|
||||
"encryption": 2,
|
||||
"rssi": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"auth": 3,
|
||||
"bssid": "000000000000",
|
||||
"encryption": 2,
|
||||
"rssi": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
{
|
||||
"auth": 4,
|
||||
"bssid": "000000000000",
|
||||
"encryption": 3,
|
||||
"rssi": 1,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
}
|
||||
],
|
||||
"wpa3_supported": "false"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
870
tests/fixtures/smartcam/TC70_3.0_1.3.11.json
vendored
Normal file
870
tests/fixtures/smartcam/TC70_3.0_1.3.11.json
vendored
Normal file
@ -0,0 +1,870 @@
|
||||
{
|
||||
"discovery_result": {
|
||||
"error_code": 0,
|
||||
"result": {
|
||||
"decrypted_data": {
|
||||
"connect_ssid": "#MASKED_SSID#",
|
||||
"connect_type": "wireless",
|
||||
"device_id": "0000000000000000000000000000000000000000",
|
||||
"http_port": 443,
|
||||
"last_alarm_time": "1734271551",
|
||||
"last_alarm_type": "motion",
|
||||
"owner": "00000000000000000000000000000000",
|
||||
"sd_status": "offline"
|
||||
},
|
||||
"device_id": "00000000000000000000000000000000",
|
||||
"device_model": "TC70",
|
||||
"device_name": "#MASKED_NAME#",
|
||||
"device_type": "SMART.IPCAMERA",
|
||||
"encrypt_info": {
|
||||
"data": "",
|
||||
"key": "",
|
||||
"sym_schm": "AES"
|
||||
},
|
||||
"encrypt_type": [
|
||||
"3"
|
||||
],
|
||||
"factory_default": false,
|
||||
"firmware_version": "1.3.11 Build 231121 Rel.39429n(4555)",
|
||||
"hardware_version": "3.0",
|
||||
"ip": "127.0.0.123",
|
||||
"is_support_iot_cloud": true,
|
||||
"mac": "5C-E9-31-00-00-00",
|
||||
"mgt_encrypt_schm": {
|
||||
"is_support_https": true
|
||||
}
|
||||
}
|
||||
},
|
||||
"getAlertPlan": {
|
||||
"msg_alarm_plan": {
|
||||
"chn1_msg_alarm_plan": {
|
||||
".name": "chn1_msg_alarm_plan",
|
||||
".type": "plan",
|
||||
"alarm_plan_1": "0000-0000,127",
|
||||
"enabled": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getAppComponentList": {
|
||||
"app_component": {
|
||||
"app_component_list": [
|
||||
{
|
||||
"name": "sdCard",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "timezone",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "system",
|
||||
"version": 3
|
||||
},
|
||||
{
|
||||
"name": "led",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "playback",
|
||||
"version": 4
|
||||
},
|
||||
{
|
||||
"name": "detection",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "alert",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "firmware",
|
||||
"version": 2
|
||||
},
|
||||
{
|
||||
"name": "account",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "quickSetup",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "ptz",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "video",
|
||||
"version": 2
|
||||
},
|
||||
{
|
||||
"name": "lensMask",
|
||||
"version": 2
|
||||
},
|
||||
{
|
||||
"name": "lightFrequency",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "dayNightMode",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "osd",
|
||||
"version": 2
|
||||
},
|
||||
{
|
||||
"name": "record",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "videoRotation",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "audio",
|
||||
"version": 2
|
||||
},
|
||||
{
|
||||
"name": "diagnose",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "msgPush",
|
||||
"version": 3
|
||||
},
|
||||
{
|
||||
"name": "deviceShare",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "tapoCare",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "blockZone",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "personDetection",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "targetTrack",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "babyCryDetection",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "needSubscriptionServiceList",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "iotCloud",
|
||||
"version": 1
|
||||
},
|
||||
{
|
||||
"name": "recordDownload",
|
||||
"version": 1
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"getAudioConfig": {
|
||||
"audio_config": {
|
||||
"microphone": {
|
||||
".name": "microphone",
|
||||
".type": "audio_config",
|
||||
"channels": "1",
|
||||
"encode_type": "G711alaw",
|
||||
"mute": "off",
|
||||
"noise_cancelling": "on",
|
||||
"sampling_rate": "8",
|
||||
"volume": "100"
|
||||
},
|
||||
"speaker": {
|
||||
".name": "speaker",
|
||||
".type": "audio_config",
|
||||
"volume": "100"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getBCDConfig": {
|
||||
"sound_detection": {
|
||||
"bcd": {
|
||||
".name": "bcd",
|
||||
".type": "on_off",
|
||||
"digital_sensitivity": "50",
|
||||
"enabled": "off",
|
||||
"sensitivity": "medium"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getCircularRecordingConfig": {
|
||||
"harddisk_manage": {
|
||||
"harddisk": {
|
||||
".name": "harddisk",
|
||||
".type": "storage",
|
||||
"loop": "on"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getClockStatus": {
|
||||
"system": {
|
||||
"clock_status": {
|
||||
"local_time": "2024-12-18 22:59:11",
|
||||
"seconds_from_1970": 1734562751
|
||||
}
|
||||
}
|
||||
},
|
||||
"getConnectionType": {
|
||||
"link_type": "wifi",
|
||||
"rssi": "4",
|
||||
"rssiValue": -50,
|
||||
"ssid": "I01BU0tFRF9TU0lEIw=="
|
||||
},
|
||||
"getDetectionConfig": {
|
||||
"motion_detection": {
|
||||
"motion_det": {
|
||||
".name": "motion_det",
|
||||
".type": "on_off",
|
||||
"digital_sensitivity": "50",
|
||||
"enabled": "on",
|
||||
"sensitivity": "medium"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getDeviceInfo": {
|
||||
"device_info": {
|
||||
"basic_info": {
|
||||
"avatar": "camera c212",
|
||||
"barcode": "",
|
||||
"dev_id": "0000000000000000000000000000000000000000",
|
||||
"device_alias": "#MASKED_NAME#",
|
||||
"device_info": "TC70 3.0 IPC",
|
||||
"device_model": "TC70",
|
||||
"device_name": "#MASKED_NAME#",
|
||||
"device_type": "SMART.IPCAMERA",
|
||||
"features": "3",
|
||||
"ffs": false,
|
||||
"has_set_location_info": 1,
|
||||
"hw_desc": "00000000000000000000000000000000",
|
||||
"hw_version": "3.0",
|
||||
"is_cal": true,
|
||||
"latitude": 0,
|
||||
"longitude": 0,
|
||||
"mac": "5C-E9-31-00-00-00",
|
||||
"oem_id": "00000000000000000000000000000000",
|
||||
"sw_version": "1.3.11 Build 231121 Rel.39429n(4555)"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getFirmwareAutoUpgradeConfig": {
|
||||
"auto_upgrade": {
|
||||
"common": {
|
||||
".name": "common",
|
||||
".type": "on_off",
|
||||
"enabled": "off",
|
||||
"random_range": "120",
|
||||
"time": "03:00"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getFirmwareUpdateStatus": {
|
||||
"cloud_config": {
|
||||
"upgrade_status": {
|
||||
"lastUpgradingSuccess": false,
|
||||
"state": "normal"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getLastAlarmInfo": {
|
||||
"system": {
|
||||
"last_alarm_info": {
|
||||
"last_alarm_time": "1734271551",
|
||||
"last_alarm_type": "motion"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getLdc": {
|
||||
"image": {
|
||||
"common": {
|
||||
".name": "common",
|
||||
".type": "para",
|
||||
"area_compensation": "default",
|
||||
"chroma": "50",
|
||||
"contrast": "50",
|
||||
"dehaze": "off",
|
||||
"exp_gain": "0",
|
||||
"exp_type": "auto",
|
||||
"focus_limited": "600",
|
||||
"focus_type": "semi_auto",
|
||||
"high_light_compensation": "off",
|
||||
"inf_delay": "10",
|
||||
"inf_end_time": "21600",
|
||||
"inf_sensitivity": "1",
|
||||
"inf_start_time": "64800",
|
||||
"inf_type": "auto",
|
||||
"light_freq_mode": "auto",
|
||||
"lock_blue_colton": "0",
|
||||
"lock_blue_gain": "0",
|
||||
"lock_gb_gain": "0",
|
||||
"lock_gr_gain": "0",
|
||||
"lock_green_colton": "0",
|
||||
"lock_red_colton": "0",
|
||||
"lock_red_gain": "0",
|
||||
"lock_source": "local",
|
||||
"luma": "50",
|
||||
"saturation": "50",
|
||||
"sharpness": "50",
|
||||
"shutter": "1/25",
|
||||
"smartir": "off",
|
||||
"smartir_level": "100",
|
||||
"wb_B_gain": "50",
|
||||
"wb_G_gain": "50",
|
||||
"wb_R_gain": "50",
|
||||
"wb_type": "auto",
|
||||
"wd_gain": "50",
|
||||
"wide_dynamic": "off"
|
||||
},
|
||||
"switch": {
|
||||
".name": "switch",
|
||||
".type": "switch_type",
|
||||
"flip_type": "off",
|
||||
"ldc": "off",
|
||||
"night_vision_mode": "inf_night_vision",
|
||||
"rotate_type": "off",
|
||||
"schedule_end_time": "64800",
|
||||
"schedule_start_time": "21600",
|
||||
"switch_mode": "common",
|
||||
"wtl_intensity_level": "5"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getLedStatus": {
|
||||
"led": {
|
||||
"config": {
|
||||
".name": "config",
|
||||
".type": "led",
|
||||
"enabled": "on"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getLensMaskConfig": {
|
||||
"lens_mask": {
|
||||
"lens_mask_info": {
|
||||
".name": "lens_mask_info",
|
||||
".type": "lens_mask_info",
|
||||
"enabled": "on"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getLightFrequencyInfo": {
|
||||
"image": {
|
||||
"common": {
|
||||
".name": "common",
|
||||
".type": "para",
|
||||
"area_compensation": "default",
|
||||
"chroma": "50",
|
||||
"contrast": "50",
|
||||
"dehaze": "off",
|
||||
"exp_gain": "0",
|
||||
"exp_type": "auto",
|
||||
"focus_limited": "600",
|
||||
"focus_type": "semi_auto",
|
||||
"high_light_compensation": "off",
|
||||
"inf_delay": "10",
|
||||
"inf_end_time": "21600",
|
||||
"inf_sensitivity": "1",
|
||||
"inf_start_time": "64800",
|
||||
"inf_type": "auto",
|
||||
"light_freq_mode": "auto",
|
||||
"lock_blue_colton": "0",
|
||||
"lock_blue_gain": "0",
|
||||
"lock_gb_gain": "0",
|
||||
"lock_gr_gain": "0",
|
||||
"lock_green_colton": "0",
|
||||
"lock_red_colton": "0",
|
||||
"lock_red_gain": "0",
|
||||
"lock_source": "local",
|
||||
"luma": "50",
|
||||
"saturation": "50",
|
||||
"sharpness": "50",
|
||||
"shutter": "1/25",
|
||||
"smartir": "off",
|
||||
"smartir_level": "100",
|
||||
"wb_B_gain": "50",
|
||||
"wb_G_gain": "50",
|
||||
"wb_R_gain": "50",
|
||||
"wb_type": "auto",
|
||||
"wd_gain": "50",
|
||||
"wide_dynamic": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getMediaEncrypt": {
|
||||
"cet": {
|
||||
"media_encrypt": {
|
||||
".name": "media_encrypt",
|
||||
".type": "on_off",
|
||||
"enabled": "on"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getMsgPushConfig": {
|
||||
"msg_push": {
|
||||
"chn1_msg_push_info": {
|
||||
".name": "chn1_msg_push_info",
|
||||
".type": "on_off",
|
||||
"notification_enabled": "on",
|
||||
"rich_notification_enabled": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getNightVisionModeConfig": {
|
||||
"image": {
|
||||
"switch": {
|
||||
".name": "switch",
|
||||
".type": "switch_type",
|
||||
"flip_type": "off",
|
||||
"ldc": "off",
|
||||
"night_vision_mode": "inf_night_vision",
|
||||
"rotate_type": "off",
|
||||
"schedule_end_time": "64800",
|
||||
"schedule_start_time": "21600",
|
||||
"switch_mode": "common",
|
||||
"wtl_intensity_level": "5"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getPersonDetectionConfig": {
|
||||
"people_detection": {
|
||||
"detection": {
|
||||
".name": "detection",
|
||||
".type": "on_off",
|
||||
"enabled": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getPresetConfig": {
|
||||
"preset": {
|
||||
"preset": {
|
||||
"id": [
|
||||
"1"
|
||||
],
|
||||
"name": [
|
||||
"Viewpoint 1"
|
||||
],
|
||||
"position_pan": [
|
||||
"0.088935"
|
||||
],
|
||||
"position_tilt": [
|
||||
"-1.000000"
|
||||
],
|
||||
"read_only": [
|
||||
"0"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"getRecordPlan": {
|
||||
"record_plan": {
|
||||
"chn1_channel": {
|
||||
".name": "chn1_channel",
|
||||
".type": "plan",
|
||||
"enabled": "on",
|
||||
"friday": "[\"0000-2400:2\"]",
|
||||
"monday": "[\"0000-2400:2\"]",
|
||||
"saturday": "[\"0000-2400:2\"]",
|
||||
"sunday": "[\"0000-2400:2\"]",
|
||||
"thursday": "[\"0000-2400:2\"]",
|
||||
"tuesday": "[\"0000-2400:2\"]",
|
||||
"wednesday": "[\"0000-2400:2\"]"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getRotationStatus": {
|
||||
"image": {
|
||||
"switch": {
|
||||
".name": "switch",
|
||||
".type": "switch_type",
|
||||
"flip_type": "off",
|
||||
"ldc": "off",
|
||||
"night_vision_mode": "inf_night_vision",
|
||||
"rotate_type": "off",
|
||||
"schedule_end_time": "64800",
|
||||
"schedule_start_time": "21600",
|
||||
"switch_mode": "common",
|
||||
"wtl_intensity_level": "5"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getSdCardStatus": {
|
||||
"harddisk_manage": {
|
||||
"hd_info": [
|
||||
{
|
||||
"hd_info_1": {
|
||||
"detect_status": "offline",
|
||||
"disk_name": "1",
|
||||
"free_space": "0B",
|
||||
"loop_record_status": "0",
|
||||
"msg_push_free_space": "0B",
|
||||
"msg_push_total_space": "0B",
|
||||
"percent": "0",
|
||||
"picture_free_space": "0B",
|
||||
"picture_total_space": "0B",
|
||||
"record_duration": "0",
|
||||
"record_free_duration": "0",
|
||||
"record_start_time": "0",
|
||||
"rw_attr": "r",
|
||||
"status": "offline",
|
||||
"total_space": "0B",
|
||||
"type": "local",
|
||||
"video_free_space": "0B",
|
||||
"video_total_space": "0B",
|
||||
"write_protect": "0"
|
||||
}
|
||||
}
|
||||
]
|
||||
}
|
||||
},
|
||||
"getTamperDetectionConfig": {
|
||||
"tamper_detection": {
|
||||
"tamper_det": {
|
||||
".name": "tamper_det",
|
||||
".type": "on_off",
|
||||
"digital_sensitivity": "50",
|
||||
"enabled": "off",
|
||||
"sensitivity": "medium"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getTargetTrackConfig": {
|
||||
"target_track": {
|
||||
"target_track_info": {
|
||||
".name": "target_track_info",
|
||||
".type": "target_track_info",
|
||||
"enabled": "off"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getTimezone": {
|
||||
"system": {
|
||||
"basic": {
|
||||
".name": "basic",
|
||||
".type": "setting",
|
||||
"timezone": "UTC-00:00",
|
||||
"timing_mode": "ntp",
|
||||
"zone_id": "Europe/London"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getVideoCapability": {
|
||||
"video_capability": {
|
||||
"main": {
|
||||
".name": "main",
|
||||
".type": "capability",
|
||||
"bitrate_types": [
|
||||
"cbr",
|
||||
"vbr"
|
||||
],
|
||||
"bitrates": [
|
||||
"256",
|
||||
"512",
|
||||
"1024",
|
||||
"2048"
|
||||
],
|
||||
"encode_types": [
|
||||
"H264"
|
||||
],
|
||||
"frame_rates": [
|
||||
"65537",
|
||||
"65546",
|
||||
"65551"
|
||||
],
|
||||
"qualitys": [
|
||||
"1",
|
||||
"3",
|
||||
"5"
|
||||
],
|
||||
"resolutions": [
|
||||
"1920*1080",
|
||||
"1280*720",
|
||||
"640*360"
|
||||
]
|
||||
}
|
||||
}
|
||||
},
|
||||
"getVideoQualities": {
|
||||
"video": {
|
||||
"main": {
|
||||
".name": "main",
|
||||
".type": "stream",
|
||||
"bitrate": "1024",
|
||||
"bitrate_type": "vbr",
|
||||
"encode_type": "H264",
|
||||
"frame_rate": "65551",
|
||||
"gop_factor": "2",
|
||||
"name": "VideoEncoder_1",
|
||||
"quality": "3",
|
||||
"resolution": "1280*720",
|
||||
"stream_type": "general"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getWhitelampConfig": {
|
||||
"image": {
|
||||
"switch": {
|
||||
".name": "switch",
|
||||
".type": "switch_type",
|
||||
"flip_type": "off",
|
||||
"ldc": "off",
|
||||
"night_vision_mode": "inf_night_vision",
|
||||
"rotate_type": "off",
|
||||
"schedule_end_time": "64800",
|
||||
"schedule_start_time": "21600",
|
||||
"switch_mode": "common",
|
||||
"wtl_intensity_level": "5"
|
||||
}
|
||||
}
|
||||
},
|
||||
"getWhitelampStatus": {
|
||||
"rest_time": 0,
|
||||
"status": 0
|
||||
},
|
||||
"get_audio_capability": {
|
||||
"get": {
|
||||
"audio_capability": {
|
||||
"device_microphone": {
|
||||
".name": "device_microphone",
|
||||
".type": "capability",
|
||||
"aec": "1",
|
||||
"channels": "1",
|
||||
"echo_cancelling": "0",
|
||||
"encode_type": [
|
||||
"G711alaw"
|
||||
],
|
||||
"half_duplex": "1",
|
||||
"mute": "1",
|
||||
"noise_cancelling": "1",
|
||||
"sampling_rate": [
|
||||
"8"
|
||||
],
|
||||
"volume": "1"
|
||||
},
|
||||
"device_speaker": {
|
||||
".name": "device_speaker",
|
||||
".type": "capability",
|
||||
"channels": "1",
|
||||
"decode_type": [
|
||||
"G711"
|
||||
],
|
||||
"mute": "0",
|
||||
"sampling_rate": [
|
||||
"8"
|
||||
],
|
||||
"volume": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"get_audio_config": {
|
||||
"get": {
|
||||
"audio_config": {
|
||||
"microphone": {
|
||||
".name": "microphone",
|
||||
".type": "audio_config",
|
||||
"channels": "1",
|
||||
"encode_type": "G711alaw",
|
||||
"mute": "off",
|
||||
"noise_cancelling": "on",
|
||||
"sampling_rate": "8",
|
||||
"volume": "100"
|
||||
},
|
||||
"speaker": {
|
||||
".name": "speaker",
|
||||
".type": "audio_config",
|
||||
"volume": "100"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"get_cet": {
|
||||
"get": {
|
||||
"cet": {
|
||||
"vhttpd": {
|
||||
".name": "vhttpd",
|
||||
".type": "server",
|
||||
"port": "8800"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"get_function": {
|
||||
"get": {
|
||||
"function": {
|
||||
"module_spec": {
|
||||
".name": "module_spec",
|
||||
".type": "module-spec",
|
||||
"ae_weighting_table_resolution": "5*5",
|
||||
"ai_enhance_capability": "1",
|
||||
"app_version": "1.0.0",
|
||||
"audio": [
|
||||
"speaker",
|
||||
"microphone"
|
||||
],
|
||||
"audioexception_detection": "0",
|
||||
"auth_encrypt": "1",
|
||||
"backlight_coexistence": "1",
|
||||
"change_password": "1",
|
||||
"client_info": "1",
|
||||
"cloud_storage_version": "1.0",
|
||||
"custom_area_compensation": "1",
|
||||
"custom_auto_mode_exposure_level": "0",
|
||||
"device_share": [
|
||||
"preview",
|
||||
"playback",
|
||||
"voice",
|
||||
"motor",
|
||||
"cloud_storage"
|
||||
],
|
||||
"download": [
|
||||
"video"
|
||||
],
|
||||
"events": [
|
||||
"motion",
|
||||
"tamper"
|
||||
],
|
||||
"greeter": "1.0",
|
||||
"http_system_state_audio_support": "1",
|
||||
"intrusion_detection": "1",
|
||||
"led": "1",
|
||||
"lens_mask": "1",
|
||||
"linecrossing_detection": "1",
|
||||
"linkage_capability": "1",
|
||||
"local_storage": "1",
|
||||
"media_encrypt": "1",
|
||||
"msg_alarm": "1",
|
||||
"msg_alarm_list": [
|
||||
"sound",
|
||||
"light"
|
||||
],
|
||||
"msg_alarm_separate_list": [
|
||||
"light",
|
||||
"sound"
|
||||
],
|
||||
"msg_push": "1",
|
||||
"multi_user": "0",
|
||||
"multicast": "0",
|
||||
"network": [
|
||||
"wifi"
|
||||
],
|
||||
"ota_upgrade": "1",
|
||||
"p2p_support_versions": [
|
||||
"1.1"
|
||||
],
|
||||
"playback": [
|
||||
"local",
|
||||
"p2p",
|
||||
"relay"
|
||||
],
|
||||
"playback_scale": "1",
|
||||
"preview": [
|
||||
"local",
|
||||
"p2p",
|
||||
"relay"
|
||||
],
|
||||
"privacy_mask_api_version": "1.0",
|
||||
"ptz": "1",
|
||||
"record_max_slot_cnt": "10",
|
||||
"record_type": [
|
||||
"timing",
|
||||
"motion"
|
||||
],
|
||||
"relay_support_versions": [
|
||||
"1.3"
|
||||
],
|
||||
"reonboarding": "1",
|
||||
"smart_detection": "1",
|
||||
"smart_msg_push_capability": "1",
|
||||
"ssl_cer_version": "1.0",
|
||||
"storage_api_version": "2.2",
|
||||
"stream_max_sessions": "10",
|
||||
"streaming_support_versions": [
|
||||
"1.0"
|
||||
],
|
||||
"target_track": "1.0",
|
||||
"timing_reboot": "1",
|
||||
"verification_change_password": "1",
|
||||
"video_codec": [
|
||||
"h264"
|
||||
],
|
||||
"video_detection_digital_sensitivity": "1",
|
||||
"wifi_cascade_connection": "1",
|
||||
"wifi_connection_info": "1",
|
||||
"wireless_hotspot": "1"
|
||||
}
|
||||
}
|
||||
}
|
||||
},
|
||||
"get_motor": {
|
||||
"get": {
|
||||
"motor": {
|
||||
"capability": {
|
||||
".name": "capability",
|
||||
".type": "ptz",
|
||||
"absolute_move_supported": "1",
|
||||
"calibrate_supported": "1",
|
||||
"continuous_move_supported": "1",
|
||||
"eflip_mode": [
|
||||
"off",
|
||||
"on"
|
||||
],
|
||||
"home_position_mode": "none",
|
||||
"limit_supported": "0",
|
||||
"manual_control_level": [
|
||||
"low",
|
||||
"normal",
|
||||
"high"
|
||||
],
|
||||
"manual_control_mode": [
|
||||
"compatible",
|
||||
"pedestrian",
|
||||
"motor_vehicle",
|
||||
"non_motor_vehicle",
|
||||
"self_adaptive"
|
||||
],
|
||||
"park_supported": "0",
|
||||
"pattern_supported": "0",
|
||||
"plan_supported": "0",
|
||||
"position_pan_range": [
|
||||
"-1.000000",
|
||||
"1.000000"
|
||||
],
|
||||
"position_tilt_range": [
|
||||
"-1.000000",
|
||||
"1.000000"
|
||||
],
|
||||
"poweroff_save_supported": "1",
|
||||
"poweroff_save_time_range": [
|
||||
"10",
|
||||
"600"
|
||||
],
|
||||
"preset_number_max": "8",
|
||||
"preset_supported": "1",
|
||||
"relative_move_supported": "1",
|
||||
"reverse_mode": [
|
||||
"off",
|
||||
"on",
|
||||
"auto"
|
||||
],
|
||||
"scan_supported": "0",
|
||||
"speed_pan_max": "1.00000",
|
||||
"speed_tilt_max": "1.000000",
|
||||
"tour_supported": "0"
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
@ -1,7 +1,14 @@
|
||||
import copy
|
||||
import logging
|
||||
from contextlib import nullcontext as does_not_raise
|
||||
from unittest.mock import patch
|
||||
|
||||
import pytest
|
||||
|
||||
from kasa import Module, SmartDevice
|
||||
from kasa import DeviceError, Module
|
||||
from kasa.exceptions import SmartErrorCode
|
||||
from kasa.interfaces.energy import Energy
|
||||
from kasa.smart import SmartDevice
|
||||
from kasa.smart.modules import Energy as SmartEnergyModule
|
||||
from tests.conftest import has_emeter_smart
|
||||
|
||||
@ -19,3 +26,84 @@ async def test_supported(dev: SmartDevice):
|
||||
assert energy_module.supports(Energy.ModuleFeature.VOLTAGE_CURRENT) is False
|
||||
else:
|
||||
assert energy_module.supports(Energy.ModuleFeature.VOLTAGE_CURRENT) is True
|
||||
|
||||
|
||||
@has_emeter_smart
|
||||
async def test_get_energy_usage_error(
|
||||
dev: SmartDevice, caplog: pytest.LogCaptureFixture
|
||||
):
|
||||
"""Test errors on get_energy_usage."""
|
||||
caplog.set_level(logging.DEBUG)
|
||||
|
||||
energy_module = dev.modules.get(Module.Energy)
|
||||
if not energy_module:
|
||||
pytest.skip(f"Energy module not supported for {dev}.")
|
||||
|
||||
version = dev._components["energy_monitoring"]
|
||||
|
||||
expected_raise = does_not_raise() if version > 1 else pytest.raises(DeviceError)
|
||||
if version > 1:
|
||||
expected = "get_energy_usage"
|
||||
expected_current_consumption = 2.002
|
||||
else:
|
||||
expected = "current_power"
|
||||
expected_current_consumption = None
|
||||
|
||||
assert expected in energy_module.data
|
||||
assert energy_module.current_consumption is not None
|
||||
assert energy_module.consumption_today is not None
|
||||
assert energy_module.consumption_this_month is not None
|
||||
|
||||
last_update = copy.deepcopy(dev._last_update)
|
||||
resp = copy.deepcopy(last_update)
|
||||
|
||||
if ed := resp.get("get_emeter_data"):
|
||||
ed["power_mw"] = 2002
|
||||
if cp := resp.get("get_current_power"):
|
||||
cp["current_power"] = 2.002
|
||||
resp["get_energy_usage"] = SmartErrorCode.JSON_DECODE_FAIL_ERROR
|
||||
|
||||
# version 1 only has get_energy_usage so module should raise an error if
|
||||
# version 1 and get_energy_usage is in error
|
||||
with patch.object(dev.protocol, "query", return_value=resp):
|
||||
await dev.update()
|
||||
|
||||
with expected_raise:
|
||||
assert "get_energy_usage" not in energy_module.data
|
||||
|
||||
assert energy_module.current_consumption == expected_current_consumption
|
||||
assert energy_module.consumption_today is None
|
||||
assert energy_module.consumption_this_month is None
|
||||
|
||||
msg = (
|
||||
f"Removed key get_energy_usage from response for device {dev.host}"
|
||||
" as it returned error: JSON_DECODE_FAIL_ERROR"
|
||||
)
|
||||
if version > 1:
|
||||
assert msg in caplog.text
|
||||
|
||||
# Now test with no get_emeter_data
|
||||
# This may not be valid scenario but we have a fallback to get_current_power
|
||||
# just in case that should be tested.
|
||||
caplog.clear()
|
||||
resp = copy.deepcopy(last_update)
|
||||
|
||||
if cp := resp.get("get_current_power"):
|
||||
cp["current_power"] = 2.002
|
||||
resp["get_energy_usage"] = SmartErrorCode.JSON_DECODE_FAIL_ERROR
|
||||
|
||||
# Remove get_emeter_data from the response and from the device which will
|
||||
# remember it otherwise.
|
||||
resp.pop("get_emeter_data", None)
|
||||
dev._last_update.pop("get_emeter_data", None)
|
||||
|
||||
with patch.object(dev.protocol, "query", return_value=resp):
|
||||
await dev.update()
|
||||
|
||||
with expected_raise:
|
||||
assert "get_energy_usage" not in energy_module.data
|
||||
|
||||
assert energy_module.current_consumption == expected_current_consumption
|
||||
|
||||
# message should only be logged once
|
||||
assert msg not in caplog.text
|
||||
|
@ -355,7 +355,7 @@ async def test_update_module_query_errors(
|
||||
if mod.name == "Energy":
|
||||
emod = cast(Energy, mod)
|
||||
with pytest.raises(KasaException, match="Module update error"):
|
||||
assert emod.current_consumption is not None
|
||||
assert emod.status is not None
|
||||
else:
|
||||
assert mod.disabled is False
|
||||
assert mod._error_count == 0
|
||||
@ -363,7 +363,7 @@ async def test_update_module_query_errors(
|
||||
# Test one of the raise_if_update_error doesn't raise
|
||||
if mod.name == "Energy":
|
||||
emod = cast(Energy, mod)
|
||||
assert emod.current_consumption is not None
|
||||
assert emod.status is not None
|
||||
|
||||
|
||||
async def test_get_modules():
|
||||
|
45
tests/smartcam/modules/test_babycrydetection.py
Normal file
45
tests/smartcam/modules/test_babycrydetection.py
Normal file
@ -0,0 +1,45 @@
|
||||
"""Tests for smartcam baby cry detection module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from kasa import Device
|
||||
from kasa.smartcam.smartcammodule import SmartCamModule
|
||||
|
||||
from ...device_fixtures import parametrize
|
||||
|
||||
babycrydetection = parametrize(
|
||||
"has babycry detection",
|
||||
component_filter="babyCryDetection",
|
||||
protocol_filter={"SMARTCAM"},
|
||||
)
|
||||
|
||||
|
||||
@babycrydetection
|
||||
async def test_babycrydetection(dev: Device):
|
||||
"""Test device babycry detection."""
|
||||
babycry = dev.modules.get(SmartCamModule.SmartCamBabyCryDetection)
|
||||
assert babycry
|
||||
|
||||
bcde_feat = dev.features.get("baby_cry_detection")
|
||||
assert bcde_feat
|
||||
|
||||
original_enabled = babycry.enabled
|
||||
|
||||
try:
|
||||
await babycry.set_enabled(not original_enabled)
|
||||
await dev.update()
|
||||
assert babycry.enabled is not original_enabled
|
||||
assert bcde_feat.value is not original_enabled
|
||||
|
||||
await babycry.set_enabled(original_enabled)
|
||||
await dev.update()
|
||||
assert babycry.enabled is original_enabled
|
||||
assert bcde_feat.value is original_enabled
|
||||
|
||||
await bcde_feat.set_value(not original_enabled)
|
||||
await dev.update()
|
||||
assert babycry.enabled is not original_enabled
|
||||
assert bcde_feat.value is not original_enabled
|
||||
|
||||
finally:
|
||||
await babycry.set_enabled(original_enabled)
|
43
tests/smartcam/modules/test_motiondetection.py
Normal file
43
tests/smartcam/modules/test_motiondetection.py
Normal file
@ -0,0 +1,43 @@
|
||||
"""Tests for smartcam motion detection module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from kasa import Device
|
||||
from kasa.smartcam.smartcammodule import SmartCamModule
|
||||
|
||||
from ...device_fixtures import parametrize
|
||||
|
||||
motiondetection = parametrize(
|
||||
"has motion detection", component_filter="detection", protocol_filter={"SMARTCAM"}
|
||||
)
|
||||
|
||||
|
||||
@motiondetection
|
||||
async def test_motiondetection(dev: Device):
|
||||
"""Test device motion detection."""
|
||||
motion = dev.modules.get(SmartCamModule.SmartCamMotionDetection)
|
||||
assert motion
|
||||
|
||||
mde_feat = dev.features.get("motion_detection")
|
||||
assert mde_feat
|
||||
|
||||
original_enabled = motion.enabled
|
||||
|
||||
try:
|
||||
await motion.set_enabled(not original_enabled)
|
||||
await dev.update()
|
||||
assert motion.enabled is not original_enabled
|
||||
assert mde_feat.value is not original_enabled
|
||||
|
||||
await motion.set_enabled(original_enabled)
|
||||
await dev.update()
|
||||
assert motion.enabled is original_enabled
|
||||
assert mde_feat.value is original_enabled
|
||||
|
||||
await mde_feat.set_value(not original_enabled)
|
||||
await dev.update()
|
||||
assert motion.enabled is not original_enabled
|
||||
assert mde_feat.value is not original_enabled
|
||||
|
||||
finally:
|
||||
await motion.set_enabled(original_enabled)
|
45
tests/smartcam/modules/test_persondetection.py
Normal file
45
tests/smartcam/modules/test_persondetection.py
Normal file
@ -0,0 +1,45 @@
|
||||
"""Tests for smartcam person detection module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from kasa import Device
|
||||
from kasa.smartcam.smartcammodule import SmartCamModule
|
||||
|
||||
from ...device_fixtures import parametrize
|
||||
|
||||
persondetection = parametrize(
|
||||
"has person detection",
|
||||
component_filter="personDetection",
|
||||
protocol_filter={"SMARTCAM"},
|
||||
)
|
||||
|
||||
|
||||
@persondetection
|
||||
async def test_persondetection(dev: Device):
|
||||
"""Test device person detection."""
|
||||
person = dev.modules.get(SmartCamModule.SmartCamPersonDetection)
|
||||
assert person
|
||||
|
||||
pde_feat = dev.features.get("person_detection")
|
||||
assert pde_feat
|
||||
|
||||
original_enabled = person.enabled
|
||||
|
||||
try:
|
||||
await person.set_enabled(not original_enabled)
|
||||
await dev.update()
|
||||
assert person.enabled is not original_enabled
|
||||
assert pde_feat.value is not original_enabled
|
||||
|
||||
await person.set_enabled(original_enabled)
|
||||
await dev.update()
|
||||
assert person.enabled is original_enabled
|
||||
assert pde_feat.value is original_enabled
|
||||
|
||||
await pde_feat.set_value(not original_enabled)
|
||||
await dev.update()
|
||||
assert person.enabled is not original_enabled
|
||||
assert pde_feat.value is not original_enabled
|
||||
|
||||
finally:
|
||||
await person.set_enabled(original_enabled)
|
45
tests/smartcam/modules/test_tamperdetection.py
Normal file
45
tests/smartcam/modules/test_tamperdetection.py
Normal file
@ -0,0 +1,45 @@
|
||||
"""Tests for smartcam tamper detection module."""
|
||||
|
||||
from __future__ import annotations
|
||||
|
||||
from kasa import Device
|
||||
from kasa.smartcam.smartcammodule import SmartCamModule
|
||||
|
||||
from ...device_fixtures import parametrize
|
||||
|
||||
tamperdetection = parametrize(
|
||||
"has tamper detection",
|
||||
component_filter="tamperDetection",
|
||||
protocol_filter={"SMARTCAM"},
|
||||
)
|
||||
|
||||
|
||||
@tamperdetection
|
||||
async def test_tamperdetection(dev: Device):
|
||||
"""Test device tamper detection."""
|
||||
tamper = dev.modules.get(SmartCamModule.SmartCamTamperDetection)
|
||||
assert tamper
|
||||
|
||||
tde_feat = dev.features.get("tamper_detection")
|
||||
assert tde_feat
|
||||
|
||||
original_enabled = tamper.enabled
|
||||
|
||||
try:
|
||||
await tamper.set_enabled(not original_enabled)
|
||||
await dev.update()
|
||||
assert tamper.enabled is not original_enabled
|
||||
assert tde_feat.value is not original_enabled
|
||||
|
||||
await tamper.set_enabled(original_enabled)
|
||||
await dev.update()
|
||||
assert tamper.enabled is original_enabled
|
||||
assert tde_feat.value is original_enabled
|
||||
|
||||
await tde_feat.set_value(not original_enabled)
|
||||
await dev.update()
|
||||
assert tamper.enabled is not original_enabled
|
||||
assert tde_feat.value is not original_enabled
|
||||
|
||||
finally:
|
||||
await tamper.set_enabled(original_enabled)
|
@ -17,10 +17,20 @@ async def test_state(dev: Device):
|
||||
if dev.device_type is DeviceType.Hub:
|
||||
pytest.skip("Hubs cannot be switched on and off")
|
||||
|
||||
state = dev.is_on
|
||||
await dev.set_state(not state)
|
||||
if Module.LensMask in dev.modules:
|
||||
state = dev.is_on
|
||||
await dev.set_state(not state)
|
||||
await dev.update()
|
||||
assert dev.is_on is not state
|
||||
|
||||
dev.modules.pop(Module.LensMask) # type: ignore[attr-defined]
|
||||
|
||||
# Test with no lens mask module. Device is always on.
|
||||
assert dev.is_on is True
|
||||
res = await dev.set_state(False)
|
||||
assert res == {}
|
||||
await dev.update()
|
||||
assert dev.is_on is not state
|
||||
assert dev.is_on is True
|
||||
|
||||
|
||||
@device_smartcam
|
||||
|
@ -122,8 +122,15 @@ async def test_list_devices(discovery_mock, runner):
|
||||
catch_exceptions=False,
|
||||
)
|
||||
assert res.exit_code == 0
|
||||
header = f"{'HOST':<15} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} {'ALIAS'}"
|
||||
row = f"{discovery_mock.ip:<15} {discovery_mock.device_type:<20} {discovery_mock.encrypt_type:<7}"
|
||||
header = (
|
||||
f"{'HOST':<15} {'MODEL':<9} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} "
|
||||
f"{'HTTPS':<5} {'LV':<3} {'ALIAS'}"
|
||||
)
|
||||
row = (
|
||||
f"{discovery_mock.ip:<15} {discovery_mock.model:<9} {discovery_mock.device_type:<20} "
|
||||
f"{discovery_mock.encrypt_type:<7} {discovery_mock.https:<5} "
|
||||
f"{discovery_mock.login_version or '-':<3}"
|
||||
)
|
||||
assert header in res.output
|
||||
assert row in res.output
|
||||
|
||||
@ -158,14 +165,26 @@ async def test_discover_raw(discovery_mock, runner, mocker):
|
||||
redact_spy.assert_called()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("exception", "expected"),
|
||||
[
|
||||
pytest.param(
|
||||
AuthenticationError("Failed to authenticate"),
|
||||
"Authentication failed",
|
||||
id="auth",
|
||||
),
|
||||
pytest.param(TimeoutError(), "Timed out", id="timeout"),
|
||||
pytest.param(Exception("Foobar"), "Error: Foobar", id="other-error"),
|
||||
],
|
||||
)
|
||||
@new_discovery
|
||||
async def test_list_auth_failed(discovery_mock, mocker, runner):
|
||||
async def test_list_update_failed(discovery_mock, mocker, runner, exception, expected):
|
||||
"""Test that device update is called on main."""
|
||||
device_class = Discover._get_device_class(discovery_mock.discovery_data)
|
||||
mocker.patch.object(
|
||||
device_class,
|
||||
"update",
|
||||
side_effect=AuthenticationError("Failed to authenticate"),
|
||||
side_effect=exception,
|
||||
)
|
||||
res = await runner.invoke(
|
||||
cli,
|
||||
@ -173,10 +192,17 @@ async def test_list_auth_failed(discovery_mock, mocker, runner):
|
||||
catch_exceptions=False,
|
||||
)
|
||||
assert res.exit_code == 0
|
||||
header = f"{'HOST':<15} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} {'ALIAS'}"
|
||||
row = f"{discovery_mock.ip:<15} {discovery_mock.device_type:<20} {discovery_mock.encrypt_type:<7} - Authentication failed"
|
||||
assert header in res.output
|
||||
assert row in res.output
|
||||
header = (
|
||||
f"{'HOST':<15} {'MODEL':<9} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} "
|
||||
f"{'HTTPS':<5} {'LV':<3} {'ALIAS'}"
|
||||
)
|
||||
row = (
|
||||
f"{discovery_mock.ip:<15} {discovery_mock.model:<9} {discovery_mock.device_type:<20} "
|
||||
f"{discovery_mock.encrypt_type:<7} {discovery_mock.https:<5} "
|
||||
f"{discovery_mock.login_version or '-':<3} - {expected}"
|
||||
)
|
||||
assert header in res.output.replace("\n", "")
|
||||
assert row in res.output.replace("\n", "")
|
||||
|
||||
|
||||
async def test_list_unsupported(unsupported_device_info, runner):
|
||||
@ -187,7 +213,10 @@ async def test_list_unsupported(unsupported_device_info, runner):
|
||||
catch_exceptions=False,
|
||||
)
|
||||
assert res.exit_code == 0
|
||||
header = f"{'HOST':<15} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} {'ALIAS'}"
|
||||
header = (
|
||||
f"{'HOST':<15} {'MODEL':<9} {'DEVICE FAMILY':<20} {'ENCRYPT':<7} "
|
||||
f"{'HTTPS':<5} {'LV':<3} {'ALIAS'}"
|
||||
)
|
||||
row = f"{'127.0.0.1':<15} UNSUPPORTED DEVICE"
|
||||
assert header in res.output
|
||||
assert row in res.output
|
||||
@ -239,7 +268,8 @@ async def test_alias(dev, runner):
|
||||
res = await runner.invoke(alias, obj=dev)
|
||||
assert f"Alias: {new_alias}" in res.output
|
||||
|
||||
await dev.set_alias(old_alias)
|
||||
# If alias is None set it back to empty string
|
||||
await dev.set_alias(old_alias or "")
|
||||
|
||||
|
||||
async def test_raw_command(dev, mocker, runner):
|
||||
|
@ -65,12 +65,13 @@ async def test_alias(dev):
|
||||
test_alias = "TEST1234"
|
||||
original = dev.alias
|
||||
|
||||
assert isinstance(original, str)
|
||||
assert isinstance(original, str | None)
|
||||
await dev.set_alias(test_alias)
|
||||
await dev.update()
|
||||
assert dev.alias == test_alias
|
||||
|
||||
await dev.set_alias(original)
|
||||
# If alias is None set it back to empty string
|
||||
await dev.set_alias(original or "")
|
||||
await dev.update()
|
||||
assert dev.alias == original
|
||||
|
||||
|
@ -13,9 +13,13 @@ import aiohttp
|
||||
import pytest # type: ignore # https://github.com/pytest-dev/pytest/issues/3342
|
||||
|
||||
from kasa import (
|
||||
BaseProtocol,
|
||||
Credentials,
|
||||
Discover,
|
||||
IotProtocol,
|
||||
KasaException,
|
||||
SmartCamProtocol,
|
||||
SmartProtocol,
|
||||
)
|
||||
from kasa.device_factory import (
|
||||
Device,
|
||||
@ -33,6 +37,16 @@ from kasa.deviceconfig import (
|
||||
DeviceFamily,
|
||||
)
|
||||
from kasa.discover import DiscoveryResult
|
||||
from kasa.transports import (
|
||||
AesTransport,
|
||||
BaseTransport,
|
||||
KlapTransport,
|
||||
KlapTransportV2,
|
||||
LinkieTransportV2,
|
||||
SslAesTransport,
|
||||
SslTransport,
|
||||
XorTransport,
|
||||
)
|
||||
|
||||
from .conftest import DISCOVERY_MOCK_IP
|
||||
|
||||
@ -203,3 +217,74 @@ async def test_device_class_from_unknown_family(caplog):
|
||||
with caplog.at_level(logging.DEBUG):
|
||||
assert get_device_class_from_family(dummy_name, https=False) == SmartDevice
|
||||
assert f"Unknown SMART device with {dummy_name}" in caplog.text
|
||||
|
||||
|
||||
# Aliases to make the test params more readable
|
||||
CP = DeviceConnectionParameters
|
||||
DF = DeviceFamily
|
||||
ET = DeviceEncryptionType
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("conn_params", "expected_protocol", "expected_transport"),
|
||||
[
|
||||
pytest.param(
|
||||
CP(DF.SmartIpCamera, ET.Aes, https=True),
|
||||
SmartCamProtocol,
|
||||
SslAesTransport,
|
||||
id="smartcam",
|
||||
),
|
||||
pytest.param(
|
||||
CP(DF.SmartTapoHub, ET.Aes, https=True),
|
||||
SmartCamProtocol,
|
||||
SslAesTransport,
|
||||
id="smartcam-hub",
|
||||
),
|
||||
pytest.param(
|
||||
CP(DF.IotIpCamera, ET.Aes, https=True),
|
||||
IotProtocol,
|
||||
LinkieTransportV2,
|
||||
id="kasacam",
|
||||
),
|
||||
pytest.param(
|
||||
CP(DF.SmartTapoRobovac, ET.Aes, https=True),
|
||||
SmartProtocol,
|
||||
SslTransport,
|
||||
id="robovac",
|
||||
),
|
||||
pytest.param(
|
||||
CP(DF.IotSmartPlugSwitch, ET.Klap, https=False),
|
||||
IotProtocol,
|
||||
KlapTransport,
|
||||
id="iot-klap",
|
||||
),
|
||||
pytest.param(
|
||||
CP(DF.IotSmartPlugSwitch, ET.Xor, https=False),
|
||||
IotProtocol,
|
||||
XorTransport,
|
||||
id="iot-xor",
|
||||
),
|
||||
pytest.param(
|
||||
CP(DF.SmartTapoPlug, ET.Aes, https=False),
|
||||
SmartProtocol,
|
||||
AesTransport,
|
||||
id="smart-aes",
|
||||
),
|
||||
pytest.param(
|
||||
CP(DF.SmartTapoPlug, ET.Klap, https=False),
|
||||
SmartProtocol,
|
||||
KlapTransportV2,
|
||||
id="smart-klap",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_get_protocol(
|
||||
conn_params: DeviceConnectionParameters,
|
||||
expected_protocol: type[BaseProtocol],
|
||||
expected_transport: type[BaseTransport],
|
||||
):
|
||||
"""Test get_protocol returns the right protocol."""
|
||||
config = DeviceConfig("127.0.0.1", connection_type=conn_params)
|
||||
protocol = get_protocol(config)
|
||||
assert isinstance(protocol, expected_protocol)
|
||||
assert isinstance(protocol._transport, expected_transport)
|
||||
|
@ -15,8 +15,10 @@ from kasa.credentials import DEFAULT_CREDENTIALS, Credentials, get_default_crede
|
||||
from kasa.deviceconfig import DeviceConfig
|
||||
from kasa.exceptions import (
|
||||
AuthenticationError,
|
||||
DeviceError,
|
||||
KasaException,
|
||||
SmartErrorCode,
|
||||
_RetryableError,
|
||||
)
|
||||
from kasa.httpclient import HttpClient
|
||||
from kasa.transports.aestransport import AesEncyptionSession
|
||||
@ -200,6 +202,64 @@ async def test_unencrypted_response(mocker, caplog):
|
||||
)
|
||||
|
||||
|
||||
async def test_device_blocked_response(mocker):
|
||||
host = "127.0.0.1"
|
||||
mock_ssl_aes_device = MockSslAesDevice(host, device_blocked=True)
|
||||
mocker.patch.object(
|
||||
aiohttp.ClientSession, "post", side_effect=mock_ssl_aes_device.post
|
||||
)
|
||||
|
||||
transport = SslAesTransport(
|
||||
config=DeviceConfig(host, credentials=Credentials(MOCK_USER, MOCK_PWD))
|
||||
)
|
||||
msg = "Device blocked for 1685 seconds"
|
||||
|
||||
with pytest.raises(DeviceError, match=msg):
|
||||
await transport.perform_handshake()
|
||||
|
||||
|
||||
@pytest.mark.parametrize(
|
||||
("response", "expected_msg"),
|
||||
[
|
||||
pytest.param(
|
||||
{"error_code": -1, "msg": "Check tapo tag failed"},
|
||||
'{"error_code": -1, "msg": "Check tapo tag failed"}',
|
||||
id="can-decrypt",
|
||||
),
|
||||
pytest.param(
|
||||
b"12345678",
|
||||
str({"result": {"response": "12345678"}, "error_code": 0}),
|
||||
id="cannot-decrypt",
|
||||
),
|
||||
],
|
||||
)
|
||||
async def test_device_500_error(mocker, response, expected_msg):
|
||||
"""Test 500 error raises retryable exception."""
|
||||
host = "127.0.0.1"
|
||||
mock_ssl_aes_device = MockSslAesDevice(host)
|
||||
mocker.patch.object(
|
||||
aiohttp.ClientSession, "post", side_effect=mock_ssl_aes_device.post
|
||||
)
|
||||
|
||||
transport = SslAesTransport(
|
||||
config=DeviceConfig(host, credentials=Credentials(MOCK_USER, MOCK_PWD))
|
||||
)
|
||||
|
||||
request = {
|
||||
"method": "getDeviceInfo",
|
||||
"params": None,
|
||||
}
|
||||
|
||||
await transport.perform_handshake()
|
||||
|
||||
mock_ssl_aes_device.put_next_response(response)
|
||||
mock_ssl_aes_device.status_code = 500
|
||||
|
||||
msg = f"Device 127.0.0.1 replied with status 500 after handshake, response: {expected_msg}"
|
||||
with pytest.raises(_RetryableError, match=msg):
|
||||
await transport.send(json_dumps(request))
|
||||
|
||||
|
||||
async def test_port_override():
|
||||
"""Test that port override sets the app_url."""
|
||||
host = "127.0.0.1"
|
||||
@ -235,6 +295,11 @@ class MockSslAesDevice:
|
||||
},
|
||||
}
|
||||
|
||||
DEVICE_BLOCKED_RESP = {
|
||||
"data": {"code": SmartErrorCode.DEVICE_BLOCKED.value, "sec_left": 1685},
|
||||
"error_code": SmartErrorCode.SESSION_EXPIRED.value,
|
||||
}
|
||||
|
||||
class _mock_response:
|
||||
def __init__(self, status, request: dict):
|
||||
self.status = status
|
||||
@ -263,6 +328,7 @@ class MockSslAesDevice:
|
||||
send_error_code=0,
|
||||
secure_passthrough_error_code=0,
|
||||
digest_password_fail=False,
|
||||
device_blocked=False,
|
||||
):
|
||||
self.host = host
|
||||
self.http_client = HttpClient(DeviceConfig(self.host))
|
||||
@ -277,6 +343,9 @@ class MockSslAesDevice:
|
||||
self.do_not_encrypt_response = do_not_encrypt_response
|
||||
self.want_default_username = want_default_username
|
||||
self.digest_password_fail = digest_password_fail
|
||||
self.device_blocked = device_blocked
|
||||
|
||||
self._next_responses: list[dict | bytes] = []
|
||||
|
||||
async def post(self, url: URL, params=None, json=None, data=None, *_, **__):
|
||||
if data:
|
||||
@ -303,6 +372,9 @@ class MockSslAesDevice:
|
||||
request_nonce = request["params"].get("cnonce")
|
||||
request_username = request["params"].get("username")
|
||||
|
||||
if self.device_blocked:
|
||||
return self._mock_response(self.status_code, self.DEVICE_BLOCKED_RESP)
|
||||
|
||||
if (self.want_default_username and request_username != MOCK_ADMIN_USER) or (
|
||||
not self.want_default_username and request_username != MOCK_USER
|
||||
):
|
||||
@ -359,11 +431,24 @@ class MockSslAesDevice:
|
||||
assert self.encryption_session
|
||||
decrypted_request = self.encryption_session.decrypt(encrypted_request.encode())
|
||||
decrypted_request_dict = json_loads(decrypted_request)
|
||||
decrypted_response = await self._post(url, decrypted_request_dict)
|
||||
async with decrypted_response:
|
||||
decrypted_response_data = await decrypted_response.read()
|
||||
|
||||
encrypted_response = self.encryption_session.encrypt(decrypted_response_data)
|
||||
if self._next_responses:
|
||||
next_response = self._next_responses.pop(0)
|
||||
if isinstance(next_response, dict):
|
||||
decrypted_response_data = json_dumps(next_response).encode()
|
||||
encrypted_response = self.encryption_session.encrypt(
|
||||
decrypted_response_data
|
||||
)
|
||||
else:
|
||||
encrypted_response = next_response
|
||||
else:
|
||||
decrypted_response = await self._post(url, decrypted_request_dict)
|
||||
async with decrypted_response:
|
||||
decrypted_response_data = await decrypted_response.read()
|
||||
encrypted_response = self.encryption_session.encrypt(
|
||||
decrypted_response_data
|
||||
)
|
||||
|
||||
response = (
|
||||
decrypted_response_data
|
||||
if self.do_not_encrypt_response
|
||||
@ -378,3 +463,6 @@ class MockSslAesDevice:
|
||||
async def _return_send_response(self, url: URL, json: dict[str, Any]):
|
||||
result = {"result": {"method": None}, "error_code": self.send_error_code}
|
||||
return self._mock_response(self.status_code, result)
|
||||
|
||||
def put_next_response(self, request: dict | bytes) -> None:
|
||||
self._next_responses.append(request)
|
||||
|
559
uv.lock
559
uv.lock
@ -3,16 +3,16 @@ requires-python = ">=3.11, <4.0"
|
||||
|
||||
[[package]]
|
||||
name = "aiohappyeyeballs"
|
||||
version = "2.4.3"
|
||||
version = "2.4.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/bc/69/2f6d5a019bd02e920a3417689a89887b39ad1e350b562f9955693d900c40/aiohappyeyeballs-2.4.3.tar.gz", hash = "sha256:75cf88a15106a5002a8eb1dab212525c00d1f4c0fa96e551c9fbe6f09a621586", size = 21809 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/7f/55/e4373e888fdacb15563ef6fa9fa8c8252476ea071e96fb46defac9f18bf2/aiohappyeyeballs-2.4.4.tar.gz", hash = "sha256:5fdd7d87889c63183afc18ce9271f9b0a7d32c2303e394468dd45d514a757745", size = 21977 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/f7/d8/120cd0fe3e8530df0539e71ba9683eade12cae103dd7543e50d15f737917/aiohappyeyeballs-2.4.3-py3-none-any.whl", hash = "sha256:8a7a83727b2756f394ab2895ea0765a0a8c475e3c71e98d43d76f22b4b435572", size = 14742 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b9/74/fbb6559de3607b3300b9be3cc64e97548d55678e44623db17820dbd20002/aiohappyeyeballs-2.4.4-py3-none-any.whl", hash = "sha256:a980909d50efcd44795c4afeca523296716d50cd756ddca6af8c65b996e27de8", size = 14756 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aiohttp"
|
||||
version = "3.11.7"
|
||||
version = "3.11.11"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "aiohappyeyeballs" },
|
||||
@ -23,65 +23,65 @@ dependencies = [
|
||||
{ name = "propcache" },
|
||||
{ name = "yarl" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/4b/cb/f9bb10e0cf6f01730b27d370b10cc15822bea4395acd687abc8cc5fed3ed/aiohttp-3.11.7.tar.gz", hash = "sha256:01a8aca4af3da85cea5c90141d23f4b0eee3cbecfd33b029a45a80f28c66c668", size = 7666482 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/fe/ed/f26db39d29cd3cb2f5a3374304c713fe5ab5a0e4c8ee25a0c45cc6adf844/aiohttp-3.11.11.tar.gz", hash = "sha256:bb49c7f1e6ebf3821a42d81d494f538107610c3a705987f53068546b0e90303e", size = 7669618 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/13/7f/272fa1adf68fe2fbebfe686a67b50cfb40d86dfe47d0441aff6f0b7c4c0e/aiohttp-3.11.7-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:cea52d11e02123f125f9055dfe0ccf1c3857225fb879e4a944fae12989e2aef2", size = 706820 },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/3c/6d612ef77cdba75364393f04c5c577481e3b5123a774eea447ada1ddd14f/aiohttp-3.11.7-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:3ce18f703b7298e7f7633efd6a90138d99a3f9a656cb52c1201e76cb5d79cf08", size = 466654 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/b8/1052667d4800cd49bb4f869f1ed42f5e9d5acd4676275e64ccc244c9c040/aiohttp-3.11.7-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:670847ee6aeb3a569cd7cdfbe0c3bec1d44828bbfbe78c5d305f7f804870ef9e", size = 454041 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/07/80fa7302314a6ee1c9278550e9d95b77a4c895999bfbc5364ed0ee28dc7c/aiohttp-3.11.7-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4dda726f89bfa5c465ba45b76515135a3ece0088dfa2da49b8bb278f3bdeea12", size = 1684778 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/30/a71eb45197ad6bb6af87dfb39be8b56417d24d916047d35ef3f164af87f4/aiohttp-3.11.7-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c25b74a811dba37c7ea6a14d99eb9402d89c8d739d50748a75f3cf994cf19c43", size = 1740992 },
|
||||
{ url = "https://files.pythonhosted.org/packages/22/74/0f9394429f3c4197129333a150a85cb2a642df30097a39dd41257f0b3bdc/aiohttp-3.11.7-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e5522ee72f95661e79db691310290c4618b86dff2d9b90baedf343fd7a08bf79", size = 1781816 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/1a/1e256b39179c98d16d53ac62f64bfcfe7c5b2c1e68b83cddd4165854524f/aiohttp-3.11.7-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1fbf41a6bbc319a7816ae0f0177c265b62f2a59ad301a0e49b395746eb2a9884", size = 1676692 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/37/f19d2e00efcabb9183b16bd91244de1d9c4ff7bf0fb5b8302e29a78f3286/aiohttp-3.11.7-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:59ee1925b5a5efdf6c4e7be51deee93984d0ac14a6897bd521b498b9916f1544", size = 1619523 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/3c/af50cf5e06b98783fd776f17077f7b7e755d461114af5d6744dc037fc3b0/aiohttp-3.11.7-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:24054fce8c6d6f33a3e35d1c603ef1b91bbcba73e3f04a22b4f2f27dac59b347", size = 1644084 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c0/a6/4e0233b085cbf2b6de573515c1eddde82f1c1f17e69347e32a5a5f2617ff/aiohttp-3.11.7-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:351849aca2c6f814575c1a485c01c17a4240413f960df1bf9f5deb0003c61a53", size = 1648332 },
|
||||
{ url = "https://files.pythonhosted.org/packages/06/20/7062e76e7817318c421c0f9d7b650fb81aaecf6d2f3a9833805b45ec2ea8/aiohttp-3.11.7-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:12724f3a211fa243570e601f65a8831372caf1a149d2f1859f68479f07efec3d", size = 1730912 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/1c/ff6ae4b1789894e6faf8a4e260cd3861cad618dc80ad15326789a7765750/aiohttp-3.11.7-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:7ea4490360b605804bea8173d2d086b6c379d6bb22ac434de605a9cbce006e7d", size = 1752619 },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/58/ddd5cba5ca245c00b04e9d28a7988b0f0eda02de494f8e62ecd2780655c2/aiohttp-3.11.7-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e0bf378db07df0a713a1e32381a1b277e62ad106d0dbe17b5479e76ec706d720", size = 1692801 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b2/fc/32d5e2070b43d3722b7ea65ddc6b03ffa39bcc4b5ab6395a825cde0872ad/aiohttp-3.11.7-cp311-cp311-win32.whl", hash = "sha256:cd8d62cab363dfe713067027a5adb4907515861f1e4ce63e7be810b83668b847", size = 414899 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/7e/50324c6d3df4540f5963def810b9927f220c99864065849a1dfcae77a6ce/aiohttp-3.11.7-cp311-cp311-win_amd64.whl", hash = "sha256:bf0e6cce113596377cadda4e3ac5fb89f095bd492226e46d91b4baef1dd16f60", size = 440938 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/1e/2e96b2526c590dcb99db0b94ac4f9b927ecc07f94735a8a941dee143d48b/aiohttp-3.11.7-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:4bb7493c3e3a36d3012b8564bd0e2783259ddd7ef3a81a74f0dbfa000fce48b7", size = 702326 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/ce/b5d7f3e68849f1f5e0b85af4ac9080b9d3c0a600857140024603653c2209/aiohttp-3.11.7-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e143b0ef9cb1a2b4f74f56d4fbe50caa7c2bb93390aff52f9398d21d89bc73ea", size = 461944 },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/fa/f4d98db1b7f8f0c3f74bdbd6d0d98cfc89984205cd33f1b8ee3f588ee5ad/aiohttp-3.11.7-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f7c58a240260822dc07f6ae32a0293dd5bccd618bb2d0f36d51c5dbd526f89c0", size = 454348 },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/f0/c238dda5dc9a3d12b76636e2cf0ea475890ac3a1c7e4ff0fd6c3cea2fc2d/aiohttp-3.11.7-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8d20cfe63a1c135d26bde8c1d0ea46fd1200884afbc523466d2f1cf517d1fe33", size = 1678795 },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/ee/3a18f792247e6d95dba13aaedc9dc317c3c6e75f4b88c2dd4b960d20ad2f/aiohttp-3.11.7-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:12e4d45847a174f77b2b9919719203769f220058f642b08504cf8b1cf185dacf", size = 1734411 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/79/3eb84243087a9a32cae821622c935107b4b55a5b21b76772e8e6c41092e9/aiohttp-3.11.7-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cf4efa2d01f697a7dbd0509891a286a4af0d86902fc594e20e3b1712c28c0106", size = 1788959 },
|
||||
{ url = "https://files.pythonhosted.org/packages/91/93/ad77782c5edfa17aafc070bef978fbfb8459b2f150595ffb01b559c136f9/aiohttp-3.11.7-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9ee6a4cdcbf54b8083dc9723cdf5f41f722c00db40ccf9ec2616e27869151129", size = 1687463 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/48/db35bd21b7877efa0be5f28385d8978c55323c5ce7685712e53f3f6c0bd9/aiohttp-3.11.7-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c6095aaf852c34f42e1bd0cf0dc32d1e4b48a90bfb5054abdbb9d64b36acadcb", size = 1618374 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/77/30f87db55c79fd145ed5fd15b92f2e820ce81065d41ae437797aaa550e3b/aiohttp-3.11.7-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1cf03d27885f8c5ebf3993a220cc84fc66375e1e6e812731f51aab2b2748f4a6", size = 1637021 },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/76/10b188b78ee18d0595af156d6a238bc60f9d8571f0f546027eb7eaf65b25/aiohttp-3.11.7-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:1a17f6a230f81eb53282503823f59d61dff14fb2a93847bf0399dc8e87817307", size = 1650792 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fa/33/4411bbb8ad04c47d0f4c7bd53332aaf350e49469cf6b65b132d4becafe27/aiohttp-3.11.7-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:481f10a1a45c5f4c4a578bbd74cff22eb64460a6549819242a87a80788461fba", size = 1696248 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/2d/6135d0dc1851a33d3faa937b20fef81340bc95e8310536d4c7f1f8ecc026/aiohttp-3.11.7-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:db37248535d1ae40735d15bdf26ad43be19e3d93ab3f3dad8507eb0f85bb8124", size = 1729188 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/76/a57ceff577ae26fe9a6f31ac799bc638ecf26e4acdf04295290b9929b349/aiohttp-3.11.7-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9d18a8b44ec8502a7fde91446cd9c9b95ce7c49f1eacc1fb2358b8907d4369fd", size = 1690038 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4b/81/b20e09003b6989a7f23a721692137a6143420a151063c750ab2a04878e3c/aiohttp-3.11.7-cp312-cp312-win32.whl", hash = "sha256:3d1c9c15d3999107cbb9b2d76ca6172e6710a12fda22434ee8bd3f432b7b17e8", size = 409887 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/0b/607c98bff1d07bb21e0c39e7711108ef9ff4f2a361a3ec1ce8dce93623a5/aiohttp-3.11.7-cp312-cp312-win_amd64.whl", hash = "sha256:018f1b04883a12e77e7fc161934c0f298865d3a484aea536a6a2ca8d909f0ba0", size = 436462 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/53/8d77186c6a33bd087714df18274cdcf6e36fd69a9e841c85b7e81a20b18e/aiohttp-3.11.7-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:241a6ca732d2766836d62c58c49ca7a93d08251daef0c1e3c850df1d1ca0cbc4", size = 695811 },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/b6/4c3d107a5406aa6f99f618afea82783f54ce2d9644020f50b9c88f6e823d/aiohttp-3.11.7-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:aa3705a8d14de39898da0fbad920b2a37b7547c3afd2a18b9b81f0223b7d0f68", size = 458530 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/05/dbf0bd3966be8ebed3beb4007a2d1356d79af4fe7c93e54f984df6385193/aiohttp-3.11.7-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:9acfc7f652b31853eed3b92095b0acf06fd5597eeea42e939bd23a17137679d5", size = 451371 },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/6a/2198580314617b6cf9c4b813b84df5832b5f8efedcb8a7e8b321a187233c/aiohttp-3.11.7-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dcefcf2915a2dbdbce37e2fc1622129a1918abfe3d06721ce9f6cdac9b6d2eaa", size = 1662905 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/65/08696fd7503f6a6f9f782bd012bf47f36d4ed179a7d8c95dba4726d5cc67/aiohttp-3.11.7-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c1f6490dd1862af5aae6cfcf2a274bffa9a5b32a8f5acb519a7ecf5a99a88866", size = 1713794 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/a3/b9a72dce6f15e2efbc09fa67c1067c4f3a3bb05661c0ae7b40799cde02b7/aiohttp-3.11.7-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f1ac5462582d6561c1c1708853a9faf612ff4e5ea5e679e99be36143d6eabd8e", size = 1770757 },
|
||||
{ url = "https://files.pythonhosted.org/packages/78/7e/8fb371b5f8c4c1eaa0d0a50750c0dd68059f86794aeb36919644815486f5/aiohttp-3.11.7-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c1a6309005acc4b2bcc577ba3b9169fea52638709ffacbd071f3503264620da", size = 1673136 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/0f/09685d13d2c7634cb808868ea29c170d4dcde4215a4a90fb86491cd3ae25/aiohttp-3.11.7-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f5b973cce96793725ef63eb449adfb74f99c043c718acb76e0d2a447ae369962", size = 1600370 },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/2e/18fd38b117f9b3a375166ccb70ed43cf7e3dfe2cc947139acc15feefc5a2/aiohttp-3.11.7-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ce91a24aac80de6be8512fb1c4838a9881aa713f44f4e91dd7bb3b34061b497d", size = 1613459 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/94/10a82abc680d753be33506be699aaa330152ecc4f316eaf081f996ee56c2/aiohttp-3.11.7-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:875f7100ce0e74af51d4139495eec4025affa1a605280f23990b6434b81df1bd", size = 1613924 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/58/897c0561f5c522dda6e173192f1e4f10144e1a7126096f17a3f12b7aa168/aiohttp-3.11.7-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c171fc35d3174bbf4787381716564042a4cbc008824d8195eede3d9b938e29a8", size = 1681164 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/8b/3a48b1cdafa612679d976274355f6a822de90b85d7dba55654ecfb01c979/aiohttp-3.11.7-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:ee9afa1b0d2293c46954f47f33e150798ad68b78925e3710044e0d67a9487791", size = 1712139 },
|
||||
{ url = "https://files.pythonhosted.org/packages/aa/9d/70ab5b4dd7900db04af72840e033aee06e472b1343e372ea256ed675511c/aiohttp-3.11.7-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8360c7cc620abb320e1b8d603c39095101391a82b1d0be05fb2225471c9c5c52", size = 1667446 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/98/b5fbcc8f6056f0c56001c75227e6b7ca9ee4f2e5572feca82ff3d65d485d/aiohttp-3.11.7-cp313-cp313-win32.whl", hash = "sha256:7a9318da4b4ada9a67c1dd84d1c0834123081e746bee311a16bb449f363d965e", size = 408689 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/07/4d1504577fa6349dd2e3839e89fb56e5dee38d64efe3d4366e9fcfda0cdb/aiohttp-3.11.7-cp313-cp313-win_amd64.whl", hash = "sha256:fc6da202068e0a268e298d7cd09b6e9f3997736cd9b060e2750963754552a0a9", size = 434809 },
|
||||
{ url = "https://files.pythonhosted.org/packages/34/ae/e8806a9f054e15f1d18b04db75c23ec38ec954a10c0a68d3bd275d7e8be3/aiohttp-3.11.11-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ba74ec819177af1ef7f59063c6d35a214a8fde6f987f7661f4f0eecc468a8f76", size = 708624 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/e0/313ef1a333fb4d58d0c55a6acb3cd772f5d7756604b455181049e222c020/aiohttp-3.11.11-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4af57160800b7a815f3fe0eba9b46bf28aafc195555f1824555fa2cfab6c1538", size = 468507 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/60/03455476bf1f467e5b4a32a465c450548b2ce724eec39d69f737191f936a/aiohttp-3.11.11-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:ffa336210cf9cd8ed117011085817d00abe4c08f99968deef0013ea283547204", size = 455571 },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/f9/469588603bd75bf02c8ffb8c8a0d4b217eed446b49d4a767684685aa33fd/aiohttp-3.11.11-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81b8fe282183e4a3c7a1b72f5ade1094ed1c6345a8f153506d114af5bf8accd9", size = 1685694 },
|
||||
{ url = "https://files.pythonhosted.org/packages/88/b9/1b7fa43faf6c8616fa94c568dc1309ffee2b6b68b04ac268e5d64b738688/aiohttp-3.11.11-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3af41686ccec6a0f2bdc66686dc0f403c41ac2089f80e2214a0f82d001052c03", size = 1743660 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/8b/0248d19dbb16b67222e75f6aecedd014656225733157e5afaf6a6a07e2e8/aiohttp-3.11.11-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70d1f9dde0e5dd9e292a6d4d00058737052b01f3532f69c0c65818dac26dc287", size = 1785421 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c4/11/f478e071815a46ca0a5ae974651ff0c7a35898c55063305a896e58aa1247/aiohttp-3.11.11-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:249cc6912405917344192b9f9ea5cd5b139d49e0d2f5c7f70bdfaf6b4dbf3a2e", size = 1675145 },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/5d/284d182fecbb5075ae10153ff7374f57314c93a8681666600e3a9e09c505/aiohttp-3.11.11-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0eb98d90b6690827dcc84c246811feeb4e1eea683c0eac6caed7549be9c84665", size = 1619804 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1b/78/980064c2ad685c64ce0e8aeeb7ef1e53f43c5b005edcd7d32e60809c4992/aiohttp-3.11.11-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:ec82bf1fda6cecce7f7b915f9196601a1bd1a3079796b76d16ae4cce6d0ef89b", size = 1654007 },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/8d/9e658d63b1438ad42b96f94da227f2e2c1d5c6001c9e8ffcc0bfb22e9105/aiohttp-3.11.11-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9fd46ce0845cfe28f108888b3ab17abff84ff695e01e73657eec3f96d72eef34", size = 1650022 },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/fd/a032bf7f2755c2df4f87f9effa34ccc1ef5cea465377dbaeef93bb56bbd6/aiohttp-3.11.11-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:bd176afcf8f5d2aed50c3647d4925d0db0579d96f75a31e77cbaf67d8a87742d", size = 1732899 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c5/0c/c2b85fde167dd440c7ba50af2aac20b5a5666392b174df54c00f888c5a75/aiohttp-3.11.11-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:ec2aa89305006fba9ffb98970db6c8221541be7bee4c1d027421d6f6df7d1ce2", size = 1755142 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/78/91ae1a3b3b3bed8b893c5d69c07023e151b1c95d79544ad04cf68f596c2f/aiohttp-3.11.11-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:92cde43018a2e17d48bb09c79e4d4cb0e236de5063ce897a5e40ac7cb4878773", size = 1692736 },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/89/a7ef9c4b4cdb546fcc650ca7f7395aaffbd267f0e1f648a436bec33c9b95/aiohttp-3.11.11-cp311-cp311-win32.whl", hash = "sha256:aba807f9569455cba566882c8938f1a549f205ee43c27b126e5450dc9f83cc62", size = 416418 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/db/2192489a8a51b52e06627506f8ac8df69ee221de88ab9bdea77aa793aa6a/aiohttp-3.11.11-cp311-cp311-win_amd64.whl", hash = "sha256:ae545f31489548c87b0cced5755cfe5a5308d00407000e72c4fa30b19c3220ac", size = 442509 },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/cf/4bda538c502f9738d6b95ada11603c05ec260807246e15e869fc3ec5de97/aiohttp-3.11.11-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e595c591a48bbc295ebf47cb91aebf9bd32f3ff76749ecf282ea7f9f6bb73886", size = 704666 },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/7b/87fcef2cad2fad420ca77bef981e815df6904047d0a1bd6aeded1b0d1d66/aiohttp-3.11.11-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3ea1b59dc06396b0b424740a10a0a63974c725b1c64736ff788a3689d36c02d2", size = 464057 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/a6/789e1f17a1b6f4a38939fbc39d29e1d960d5f89f73d0629a939410171bc0/aiohttp-3.11.11-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8811f3f098a78ffa16e0ea36dffd577eb031aea797cbdba81be039a4169e242c", size = 455996 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/dd/485061fbfef33165ce7320db36e530cd7116ee1098e9c3774d15a732b3fd/aiohttp-3.11.11-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bd7227b87a355ce1f4bf83bfae4399b1f5bb42e0259cb9405824bd03d2f4336a", size = 1682367 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/d7/9ec5b3ea9ae215c311d88b2093e8da17e67b8856673e4166c994e117ee3e/aiohttp-3.11.11-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d40f9da8cabbf295d3a9dae1295c69975b86d941bc20f0a087f0477fa0a66231", size = 1736989 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d6/fb/ea94927f7bfe1d86178c9d3e0a8c54f651a0a655214cce930b3c679b8f64/aiohttp-3.11.11-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ffb3dc385f6bb1568aa974fe65da84723210e5d9707e360e9ecb51f59406cd2e", size = 1793265 },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/7f/6de218084f9b653026bd7063cd8045123a7ba90c25176465f266976d8c82/aiohttp-3.11.11-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a8f5f7515f3552d899c61202d99dcb17d6e3b0de777900405611cd747cecd1b8", size = 1691841 },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/e2/992f43d87831cbddb6b09c57ab55499332f60ad6fdbf438ff4419c2925fc/aiohttp-3.11.11-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3499c7ffbfd9c6a3d8d6a2b01c26639da7e43d47c7b4f788016226b1e711caa8", size = 1619317 },
|
||||
{ url = "https://files.pythonhosted.org/packages/96/74/879b23cdd816db4133325a201287c95bef4ce669acde37f8f1b8669e1755/aiohttp-3.11.11-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8e2bf8029dbf0810c7bfbc3e594b51c4cc9101fbffb583a3923aea184724203c", size = 1641416 },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/98/b123f6b15d87c54e58fd7ae3558ff594f898d7f30a90899718f3215ad328/aiohttp-3.11.11-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b6212a60e5c482ef90f2d788835387070a88d52cf6241d3916733c9176d39eab", size = 1646514 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d7/38/257fda3dc99d6978ab943141d5165ec74fd4b4164baa15e9c66fa21da86b/aiohttp-3.11.11-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:d119fafe7b634dbfa25a8c597718e69a930e4847f0b88e172744be24515140da", size = 1702095 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/f4/ddab089053f9fb96654df5505c0a69bde093214b3c3454f6bfdb1845f558/aiohttp-3.11.11-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:6fba278063559acc730abf49845d0e9a9e1ba74f85f0ee6efd5803f08b285853", size = 1734611 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/d6/f30b2bc520c38c8aa4657ed953186e535ae84abe55c08d0f70acd72ff577/aiohttp-3.11.11-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:92fc484e34b733704ad77210c7957679c5c3877bd1e6b6d74b185e9320cc716e", size = 1694576 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/97/b0a88c3f4c6d0020b34045ee6d954058abc870814f6e310c4c9b74254116/aiohttp-3.11.11-cp312-cp312-win32.whl", hash = "sha256:9f5b3c1ed63c8fa937a920b6c1bec78b74ee09593b3f5b979ab2ae5ef60d7600", size = 411363 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/23/cc36d9c398980acaeeb443100f0216f50a7cfe20c67a9fd0a2f1a5a846de/aiohttp-3.11.11-cp312-cp312-win_amd64.whl", hash = "sha256:1e69966ea6ef0c14ee53ef7a3d68b564cc408121ea56c0caa2dc918c1b2f553d", size = 437666 },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/d1/d8af164f400bad432b63e1ac857d74a09311a8334b0481f2f64b158b50eb/aiohttp-3.11.11-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:541d823548ab69d13d23730a06f97460f4238ad2e5ed966aaf850d7c369782d9", size = 697982 },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/d1/faad3bf9fa4bfd26b95c69fc2e98937d52b1ff44f7e28131855a98d23a17/aiohttp-3.11.11-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:929f3ed33743a49ab127c58c3e0a827de0664bfcda566108989a14068f820194", size = 460662 },
|
||||
{ url = "https://files.pythonhosted.org/packages/db/61/0d71cc66d63909dabc4590f74eba71f91873a77ea52424401c2498d47536/aiohttp-3.11.11-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0882c2820fd0132240edbb4a51eb8ceb6eef8181db9ad5291ab3332e0d71df5f", size = 452950 },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/db/6d04bc7fd92784900704e16b745484ef45b77bd04e25f58f6febaadf7983/aiohttp-3.11.11-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b63de12e44935d5aca7ed7ed98a255a11e5cb47f83a9fded7a5e41c40277d104", size = 1665178 },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/5c/e95ade9ae29f375411884d9fd98e50535bf9fe316c9feb0f30cd2ac8f508/aiohttp-3.11.11-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa54f8ef31d23c506910c21163f22b124facb573bff73930735cf9fe38bf7dff", size = 1717939 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/1c/1e7d5c5daea9e409ed70f7986001b8c9e3a49a50b28404498d30860edab6/aiohttp-3.11.11-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a344d5dc18074e3872777b62f5f7d584ae4344cd6006c17ba12103759d407af3", size = 1775125 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5d/66/890987e44f7d2f33a130e37e01a164168e6aff06fce15217b6eaf14df4f6/aiohttp-3.11.11-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b7fb429ab1aafa1f48578eb315ca45bd46e9c37de11fe45c7f5f4138091e2f1", size = 1677176 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8f/dc/e2ba57d7a52df6cdf1072fd5fa9c6301a68e1cd67415f189805d3eeb031d/aiohttp-3.11.11-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c341c7d868750e31961d6d8e60ff040fb9d3d3a46d77fd85e1ab8e76c3e9a5c4", size = 1603192 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6c/9e/8d08a57de79ca3a358da449405555e668f2c8871a7777ecd2f0e3912c272/aiohttp-3.11.11-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ed9ee95614a71e87f1a70bc81603f6c6760128b140bc4030abe6abaa988f1c3d", size = 1618296 },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/51/89822e3ec72db352c32e7fc1c690370e24e231837d9abd056490f3a49886/aiohttp-3.11.11-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:de8d38f1c2810fa2a4f1d995a2e9c70bb8737b18da04ac2afbf3971f65781d87", size = 1616524 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2c/fa/e2e6d9398f462ffaa095e84717c1732916a57f1814502929ed67dd7568ef/aiohttp-3.11.11-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a9b7371665d4f00deb8f32208c7c5e652059b0fda41cf6dbcac6114a041f1cc2", size = 1685471 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/5f/6bb976e619ca28a052e2c0ca7b0251ccd893f93d7c24a96abea38e332bf6/aiohttp-3.11.11-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:620598717fce1b3bd14dd09947ea53e1ad510317c85dda2c9c65b622edc96b12", size = 1715312 },
|
||||
{ url = "https://files.pythonhosted.org/packages/79/c1/756a7e65aa087c7fac724d6c4c038f2faaa2a42fe56dbc1dd62a33ca7213/aiohttp-3.11.11-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:bf8d9bfee991d8acc72d060d53860f356e07a50f0e0d09a8dfedea1c554dd0d5", size = 1672783 },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/ba/a6190ebb02176c7f75e6308da31f5d49f6477b651a3dcfaaaca865a298e2/aiohttp-3.11.11-cp313-cp313-win32.whl", hash = "sha256:9d73ee3725b7a737ad86c2eac5c57a4a97793d9f442599bea5ec67ac9f4bdc3d", size = 410229 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b8/62/c9fa5bafe03186a0e4699150a7fed9b1e73240996d0d2f0e5f70f3fdf471/aiohttp-3.11.11-cp313-cp313-win_amd64.whl", hash = "sha256:c7a06301c2fb096bdb0bd25fe2011531c1453b9f2c163c8031600ec73af1cc99", size = 436081 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "aiosignal"
|
||||
version = "1.3.1"
|
||||
version = "1.3.2"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "frozenlist" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ae/67/0952ed97a9793b4958e5736f6d2b346b414a2cd63e82d05940032f45b32f/aiosignal-1.3.1.tar.gz", hash = "sha256:54cd96e15e1649b75d6c87526a6ff0b6c1b0dd3459f43d9ca11d48c339b68cfc", size = 19422 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ba/b5/6d55e80f6d8a08ce22b982eafa278d823b541c925f11ee774b0b9c43473d/aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54", size = 19424 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/76/ac/a7305707cb852b7e16ff80eaf5692309bde30e2b1100a1fcacdc8f731d97/aiosignal-1.3.1-py3-none-any.whl", hash = "sha256:f8376fb07dd1e86a584e4fcdec80b36b7f81aac666ebc724e2c090300dd83b17", size = 7617 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ec/6a/bc7e17a3e87a2985d3e8f4da4cd0f481060eb78fb08596c42be62c90a4d9/aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5", size = 7597 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -95,15 +95,16 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "anyio"
|
||||
version = "4.6.2.post1"
|
||||
version = "4.7.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "idna" },
|
||||
{ name = "sniffio" },
|
||||
{ name = "typing-extensions", marker = "python_full_version < '3.13'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/9f/09/45b9b7a6d4e45c6bcb5bf61d19e3ab87df68e0601fa8c5293de3542546cc/anyio-4.6.2.post1.tar.gz", hash = "sha256:4c8bc31ccdb51c7f7bd251f51c609e038d63e34219b44aa86e47576389880b4c", size = 173422 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/f6/40/318e58f669b1a9e00f5c4453910682e2d9dd594334539c7b7817dabb765f/anyio-4.7.0.tar.gz", hash = "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48", size = 177076 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e4/f5/f2b75d2fc6f1a260f340f0e7c6a060f4dd2961cc16884ed851b0d18da06a/anyio-4.6.2.post1-py3-none-any.whl", hash = "sha256:6d170c36fba3bdd840c73d3868c1e777e33676a69c3a72cf0a0d5d6d8009b61d", size = 90377 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/7a/4daaf3b6c08ad7ceffea4634ec206faeff697526421c20f07628c7372156/anyio-4.7.0-py3-none-any.whl", hash = "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352", size = 93052 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -130,11 +131,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "attrs"
|
||||
version = "24.2.0"
|
||||
version = "24.3.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/fc/0f/aafca9af9315aee06a89ffde799a10a582fe8de76c563ee80bbcdc08b3fb/attrs-24.2.0.tar.gz", hash = "sha256:5cfb1b9148b5b086569baec03f20d7b6bf3bcacc9a42bebf87ffaaca362f6346", size = 792678 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/48/c8/6260f8ccc11f0917360fc0da435c5c9c7504e3db174d5a12a1494887b045/attrs-24.3.0.tar.gz", hash = "sha256:8f5c07333d543103541ba7be0e2ce16eeee8130cb0b3f9238ab904ce1e85baff", size = 805984 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/21/5b6702a7f963e95456c0de2d495f67bf5fd62840ac655dc451586d23d39a/attrs-24.2.0-py3-none-any.whl", hash = "sha256:81921eb96de3191c8258c199618104dd27ac608d9366f5e35d011eae1867ede2", size = 63001 },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/aa/ab0f7891a01eeb2d2e338ae8fecbe57fcebea1a24dbb64d45801bfab481d/attrs-24.3.0-py3-none-any.whl", hash = "sha256:ac96cd038792094f438ad1f6ff80837353805ac950cd2aa0e0625ef19850c308", size = 63397 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -148,11 +149,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "certifi"
|
||||
version = "2024.8.30"
|
||||
version = "2024.12.14"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b0/ee/9b19140fe824b367c04c5e1b369942dd754c4c5462d5674002f75c4dedc1/certifi-2024.8.30.tar.gz", hash = "sha256:bec941d2aa8195e248a60b31ff9f0558284cf01a52591ceda73ea9afffd69fd9", size = 168507 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0f/bd/1d41ee578ce09523c81a15426705dd20969f5abf006d1afe8aeff0dd776a/certifi-2024.12.14.tar.gz", hash = "sha256:b650d30f370c2b724812bee08008be0c4163b163ddaec3f2546c1caf65f191db", size = 166010 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/12/90/3c9ff0512038035f59d279fddeb79f5f1eccd8859f06d6163c58798b9487/certifi-2024.8.30-py3-none-any.whl", hash = "sha256:922820b53db7a7257ffbda3f597266d435245903d80737e34f8a45ff3e3230d8", size = 167321 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/32/8f6669fc4798494966bf446c8c4a162e0b5d893dff088afddf76414f70e1/certifi-2024.12.14-py3-none-any.whl", hash = "sha256:1275f7a45be9464efc1173084eaa30f866fe2e47d389406136d332ed4967ec56", size = 164927 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -287,50 +288,50 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "coverage"
|
||||
version = "7.6.8"
|
||||
version = "7.6.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/ab/75/aecfd0a3adbec6e45753976bc2a9fed62b42cea9a206d10fd29244a77953/coverage-7.6.8.tar.gz", hash = "sha256:8b2b8503edb06822c86d82fa64a4a5cb0760bb8f31f26e138ec743f422f37cfc", size = 801425 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5b/d2/c25011f4d036cf7e8acbbee07a8e09e9018390aee25ba085596c4b83d510/coverage-7.6.9.tar.gz", hash = "sha256:4a8d8977b0c6ef5aeadcb644da9e69ae0dcfe66ec7f368c89c72e058bd71164d", size = 801710 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/9f/e98211980f6e2f439e251737482aa77906c9b9c507824c71a2ce7eea0402/coverage-7.6.8-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:86cffe9c6dfcfe22e28027069725c7f57f4b868a3f86e81d1c62462764dc46d4", size = 207093 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/c7/8bab83fb9c20f7f8163c5a20dcb62d591b906a214a6dc6b07413074afc80/coverage-7.6.8-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d82ab6816c3277dc962cfcdc85b1efa0e5f50fb2c449432deaf2398a2928ab94", size = 207536 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/d6/00243df625f1b282bb25c83ce153ae2c06f8e7a796a8d833e7235337b4d9/coverage-7.6.8-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13690e923a3932e4fad4c0ebfb9cb5988e03d9dcb4c5150b5fcbf58fd8bddfc4", size = 239482 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/07/faf04b3eeb55ffc2a6f24b65dffe6e0359ec3b283e6efb5050ea0707446f/coverage-7.6.8-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4be32da0c3827ac9132bb488d331cb32e8d9638dd41a0557c5569d57cf22c9c1", size = 236886 },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/23/c79e497bf4d8fcacd316bebe1d559c765485b8ec23ac4e23025be6bfce09/coverage-7.6.8-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44e6c85bbdc809383b509d732b06419fb4544dca29ebe18480379633623baafb", size = 238749 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/e5/791bae13be3c6451e32ef7af1192e711c6a319f3c597e9b218d148fd0633/coverage-7.6.8-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:768939f7c4353c0fac2f7c37897e10b1414b571fd85dd9fc49e6a87e37a2e0d8", size = 237679 },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/c6/bbfdfb03aada601fb8993ced17468c8c8e0b4aafb3097026e680fabb7ce1/coverage-7.6.8-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e44961e36cb13c495806d4cac67640ac2866cb99044e210895b506c26ee63d3a", size = 236317 },
|
||||
{ url = "https://files.pythonhosted.org/packages/67/f9/f8e5a4b2ce96d1b0e83ae6246369eb8437001dc80ec03bb51c87ff557cd8/coverage-7.6.8-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:3ea8bb1ab9558374c0ab591783808511d135a833c3ca64a18ec927f20c4030f0", size = 237084 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/70/b05328901e4debe76e033717e1452d00246c458c44e9dbd893e7619c2967/coverage-7.6.8-cp311-cp311-win32.whl", hash = "sha256:629a1ba2115dce8bf75a5cce9f2486ae483cb89c0145795603d6554bdc83e801", size = 209638 },
|
||||
{ url = "https://files.pythonhosted.org/packages/70/55/1efa24f960a2fa9fbc44a9523d3f3c50ceb94dd1e8cd732168ab2dc41b07/coverage-7.6.8-cp311-cp311-win_amd64.whl", hash = "sha256:fb9fc32399dca861584d96eccd6c980b69bbcd7c228d06fb74fe53e007aa8ef9", size = 210506 },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/ce/3edf581c8fe429ed8ced6e6d9ac693c25975ef9093413276dab6ed68a80a/coverage-7.6.8-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:e683e6ecc587643f8cde8f5da6768e9d165cd31edf39ee90ed7034f9ca0eefee", size = 207285 },
|
||||
{ url = "https://files.pythonhosted.org/packages/09/9c/cf102ab046c9cf8895c3f7aadcde6f489a4b2ec326757e8c6e6581829b5e/coverage-7.6.8-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1defe91d41ce1bd44b40fabf071e6a01a5aa14de4a31b986aa9dfd1b3e3e414a", size = 207522 },
|
||||
{ url = "https://files.pythonhosted.org/packages/39/06/42aa6dd13dbfca72e1fd8ffccadbc921b6e75db34545ebab4d955d1e7ad3/coverage-7.6.8-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7ad66e8e50225ebf4236368cc43c37f59d5e6728f15f6e258c8639fa0dd8e6d", size = 240543 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/20/2932971dc215adeca8eeff446266a7fef17a0c238e881ffedebe7bfa0669/coverage-7.6.8-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3fe47da3e4fda5f1abb5709c156eca207eacf8007304ce3019eb001e7a7204cb", size = 237577 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/85/4323ece0cd5452c9522f4b6e5cc461e6c7149a4b1887c9e7a8b1f4e51146/coverage-7.6.8-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:202a2d645c5a46b84992f55b0a3affe4f0ba6b4c611abec32ee88358db4bb649", size = 239646 },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/52/b2537487d8f36241e518e84db6f79e26bc3343b14844366e35b090fae0d4/coverage-7.6.8-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:4674f0daa1823c295845b6a740d98a840d7a1c11df00d1fd62614545c1583787", size = 239128 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/99/7f007762012186547d0ecc3d328da6b6f31a8c99f05dc1e13dcd929918cd/coverage-7.6.8-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:74610105ebd6f33d7c10f8907afed696e79c59e3043c5f20eaa3a46fddf33b4c", size = 237434 },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/53/e9b5cf0682a1cab9352adfac73caae0d77ae1d65abc88975d510f7816389/coverage-7.6.8-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:37cda8712145917105e07aab96388ae76e787270ec04bcb9d5cc786d7cbb8443", size = 239095 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/50/054f0b464fbae0483217186478eefa2e7df3a79917ed7f1d430b6da2cf0d/coverage-7.6.8-cp312-cp312-win32.whl", hash = "sha256:9e89d5c8509fbd6c03d0dd1972925b22f50db0792ce06324ba069f10787429ad", size = 209895 },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/d0/09ba870360a27ecf09e177ca2ff59d4337fc7197b456f22ceff85cffcfa5/coverage-7.6.8-cp312-cp312-win_amd64.whl", hash = "sha256:379c111d3558272a2cae3d8e57e6b6e6f4fe652905692d54bad5ea0ca37c5ad4", size = 210684 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/84/6f0ccf94a098ac3d6d6f236bd3905eeac049a9e0efcd9a63d4feca37ac4b/coverage-7.6.8-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0b0c69f4f724c64dfbfe79f5dfb503b42fe6127b8d479b2677f2b227478db2eb", size = 207313 },
|
||||
{ url = "https://files.pythonhosted.org/packages/db/2b/e3b3a3a12ebec738c545897ac9f314620470fcbc368cdac88cf14974ba20/coverage-7.6.8-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:c15b32a7aca8038ed7644f854bf17b663bc38e1671b5d6f43f9a2b2bd0c46f63", size = 207574 },
|
||||
{ url = "https://files.pythonhosted.org/packages/db/c0/5bf95d42b6a8d21dfce5025ce187f15db57d6460a59b67a95fe8728162f1/coverage-7.6.8-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63068a11171e4276f6ece913bde059e77c713b48c3a848814a6537f35afb8365", size = 240090 },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/b8/d6fd17d1a8e2b0e1a4e8b9cb1f0f261afd422570735899759c0584236916/coverage-7.6.8-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:6f4548c5ead23ad13fb7a2c8ea541357474ec13c2b736feb02e19a3085fac002", size = 237237 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d4/e4/a91e9bb46809c8b63e68fc5db5c4d567d3423b6691d049a4f950e38fbe9d/coverage-7.6.8-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b4b4299dd0d2c67caaaf286d58aef5e75b125b95615dda4542561a5a566a1e3", size = 239225 },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/9c/9b99b0591ec4555b7292d271e005f27b465388ce166056c435b288db6a69/coverage-7.6.8-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:c9ebfb2507751f7196995142f057d1324afdab56db1d9743aab7f50289abd022", size = 238888 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/85/285c2df9a04bc7c31f21fd9d4a24d19e040ec5e2ff06e572af1f6514c9e7/coverage-7.6.8-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:c1b4474beee02ede1eef86c25ad4600a424fe36cff01a6103cb4533c6bf0169e", size = 236974 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/a1/95ec8522206f76cdca033bf8bb61fff56429fb414835fc4d34651dfd29fc/coverage-7.6.8-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:d9fd2547e6decdbf985d579cf3fc78e4c1d662b9b0ff7cc7862baaab71c9cc5b", size = 238815 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/ac/687e9ba5e6d0979e9dab5c02e01c4f24ac58260ef82d88d3b433b3f84f1e/coverage-7.6.8-cp313-cp313-win32.whl", hash = "sha256:8aae5aea53cbfe024919715eca696b1a3201886ce83790537d1c3668459c7146", size = 209957 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/a3/b61cc8e3fcf075293fb0f3dee405748453c5ba28ac02ceb4a87f52bdb105/coverage-7.6.8-cp313-cp313-win_amd64.whl", hash = "sha256:ae270e79f7e169ccfe23284ff5ea2d52a6f401dc01b337efb54b3783e2ce3f28", size = 210711 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ee/4b/891c8b9acf1b62c85e4a71dac142ab9284e8347409b7355de02e3f38306f/coverage-7.6.8-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:de38add67a0af869b0d79c525d3e4588ac1ffa92f39116dbe0ed9753f26eba7d", size = 208053 },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/a9/9e330409b291cc002723d339346452800e78df1ce50774ca439ade1d374f/coverage-7.6.8-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:b07c25d52b1c16ce5de088046cd2432b30f9ad5e224ff17c8f496d9cb7d1d451", size = 208329 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/0d/33635fd429f6589c6e1cdfc7bf581aefe4c1792fbff06383f9d37f59db60/coverage-7.6.8-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:62a66ff235e4c2e37ed3b6104d8b478d767ff73838d1222132a7a026aa548764", size = 251052 },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/32/8a08da0e46f3830bbb9a5b40614241b2e700f27a9c2889f53122486443ed/coverage-7.6.8-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:09b9f848b28081e7b975a3626e9081574a7b9196cde26604540582da60235fdf", size = 246765 },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/3f/3b86303d2c14350fdb1c6c4dbf9bc76000af2382f42ca1d4d99c6317666e/coverage-7.6.8-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:093896e530c38c8e9c996901858ac63f3d4171268db2c9c8b373a228f459bbc5", size = 249125 },
|
||||
{ url = "https://files.pythonhosted.org/packages/36/cb/c4f081b9023f9fd8646dbc4ef77be0df090263e8f66f4ea47681e0dc2cff/coverage-7.6.8-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9a7b8ac36fd688c8361cbc7bf1cb5866977ece6e0b17c34aa0df58bda4fa18a4", size = 248615 },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/ee/53bdbf67760928c44b57b2c28a8c0a4bf544f85a9ee129a63ba5c78fdee4/coverage-7.6.8-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:38c51297b35b3ed91670e1e4efb702b790002e3245a28c76e627478aa3c10d83", size = 246507 },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/49/5a57910bd0af6d8e802b4ca65292576d19b54b49f81577fd898505dee075/coverage-7.6.8-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:2e4e0f60cb4bd7396108823548e82fdab72d4d8a65e58e2c19bbbc2f1e2bfa4b", size = 247785 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/37/e450c9f6b297c79bb9858407396ed3e084dcc22990dd110ab01d5ceb9770/coverage-7.6.8-cp313-cp313t-win32.whl", hash = "sha256:6535d996f6537ecb298b4e287a855f37deaf64ff007162ec0afb9ab8ba3b8b71", size = 210605 },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/79/7d0c7dd237c6905018e2936cd1055fe1d42e7eba2ebab3c00f4aad2a27d7/coverage-7.6.8-cp313-cp313t-win_amd64.whl", hash = "sha256:c79c0685f142ca53256722a384540832420dff4ab15fec1863d7e5bc8691bdcc", size = 211777 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/91/b3dc2f7f38b5cca1236ab6bbb03e84046dd887707b4ec1db2baa47493b3b/coverage-7.6.9-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:932fc826442132dde42ee52cf66d941f581c685a6313feebed358411238f60f9", size = 207133 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/2b/53fd6cb34d443429a92b3ec737f4953627e38b3bee2a67a3c03425ba8573/coverage-7.6.9-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:085161be5f3b30fd9b3e7b9a8c301f935c8313dcf928a07b116324abea2c1c2c", size = 207577 },
|
||||
{ url = "https://files.pythonhosted.org/packages/74/f2/68edb1e6826f980a124f21ea5be0d324180bf11de6fd1defcf9604f76df0/coverage-7.6.9-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ccc660a77e1c2bf24ddbce969af9447a9474790160cfb23de6be4fa88e3951c7", size = 239524 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d3/83/8fec0ee68c2c4a5ab5f0f8527277f84ed6f2bd1310ae8a19d0c5532253ab/coverage-7.6.9-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c69e42c892c018cd3c8d90da61d845f50a8243062b19d228189b0224150018a9", size = 236925 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/20/8f50e7c7ad271144afbc2c1c6ec5541a8c81773f59352f8db544cad1a0ec/coverage-7.6.9-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0824a28ec542a0be22f60c6ac36d679e0e262e5353203bea81d44ee81fe9c6d4", size = 238792 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6f/62/4ac2e5ad9e7a5c9ec351f38947528e11541f1f00e8a0cdce56f1ba7ae301/coverage-7.6.9-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4401ae5fc52ad8d26d2a5d8a7428b0f0c72431683f8e63e42e70606374c311a1", size = 237682 },
|
||||
{ url = "https://files.pythonhosted.org/packages/58/2f/9d2203f012f3b0533c73336c74134b608742be1ce475a5c72012573cfbb4/coverage-7.6.9-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:98caba4476a6c8d59ec1eb00c7dd862ba9beca34085642d46ed503cc2d440d4b", size = 236310 },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/6d/31f6ab0b4f0f781636075f757eb02141ea1b34466d9d1526dbc586ed7078/coverage-7.6.9-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ee5defd1733fd6ec08b168bd4f5387d5b322f45ca9e0e6c817ea6c4cd36313e3", size = 237096 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/fb/e14c38adebbda9ed8b5f7f8e03340ac05d68d27b24397f8d47478927a333/coverage-7.6.9-cp311-cp311-win32.whl", hash = "sha256:f2d1ec60d6d256bdf298cb86b78dd715980828f50c46701abc3b0a2b3f8a0dc0", size = 209682 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/11/a782af39b019066af83fdc0e8825faaccbe9d7b19a803ddb753114b429cc/coverage-7.6.9-cp311-cp311-win_amd64.whl", hash = "sha256:0d59fd927b1f04de57a2ba0137166d31c1a6dd9e764ad4af552912d70428c92b", size = 210542 },
|
||||
{ url = "https://files.pythonhosted.org/packages/60/52/b16af8989a2daf0f80a88522bd8e8eed90b5fcbdecf02a6888f3e80f6ba7/coverage-7.6.9-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:99e266ae0b5d15f1ca8d278a668df6f51cc4b854513daab5cae695ed7b721cf8", size = 207325 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/79/6b7826fca8846c1216a113227b9f114ac3e6eacf168b4adcad0cb974aaca/coverage-7.6.9-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:9901d36492009a0a9b94b20e52ebfc8453bf49bb2b27bca2c9706f8b4f5a554a", size = 207563 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/07/0bc73da0ccaf45d0d64ef86d33b7d7fdeef84b4c44bf6b85fb12c215c5a6/coverage-7.6.9-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abd3e72dd5b97e3af4246cdada7738ef0e608168de952b837b8dd7e90341f015", size = 240580 },
|
||||
{ url = "https://files.pythonhosted.org/packages/71/8a/9761f409910961647d892454687cedbaccb99aae828f49486734a82ede6e/coverage-7.6.9-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ff74026a461eb0660366fb01c650c1d00f833a086b336bdad7ab00cc952072b3", size = 237613 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/10/ee7d696a17ac94f32f2dbda1e17e730bf798ae9931aec1fc01c1944cd4de/coverage-7.6.9-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:65dad5a248823a4996724a88eb51d4b31587aa7aa428562dbe459c684e5787ae", size = 239684 },
|
||||
{ url = "https://files.pythonhosted.org/packages/16/60/aa1066040d3c52fff051243c2d6ccda264da72dc6d199d047624d395b2b2/coverage-7.6.9-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:22be16571504c9ccea919fcedb459d5ab20d41172056206eb2994e2ff06118a4", size = 239112 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/e5/69f35344c6f932ba9028bf168d14a79fedb0dd4849b796d43c81ce75a3c9/coverage-7.6.9-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f957943bc718b87144ecaee70762bc2bc3f1a7a53c7b861103546d3a403f0a6", size = 237428 },
|
||||
{ url = "https://files.pythonhosted.org/packages/32/20/adc895523c4a28f63441b8ac645abd74f9bdd499d2d175bef5b41fc7f92d/coverage-7.6.9-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:0ae1387db4aecb1f485fb70a6c0148c6cdaebb6038f1d40089b1fc84a5db556f", size = 239098 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/a6/e0e74230c9bb3549ec8ffc137cfd16ea5d56e993d6bffed2218bff6187e3/coverage-7.6.9-cp312-cp312-win32.whl", hash = "sha256:1a330812d9cc7ac2182586f6d41b4d0fadf9be9049f350e0efb275c8ee8eb692", size = 209940 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3e/18/cb5b88349d4aa2f41ec78d65f92ea32572b30b3f55bc2b70e87578b8f434/coverage-7.6.9-cp312-cp312-win_amd64.whl", hash = "sha256:b12c6b18269ca471eedd41c1b6a1065b2f7827508edb9a7ed5555e9a56dcfc97", size = 210726 },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/26/9abab6539d2191dbda2ce8c97b67d74cbfc966cc5b25abb880ffc7c459bc/coverage-7.6.9-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:899b8cd4781c400454f2f64f7776a5d87bbd7b3e7f7bda0cb18f857bb1334664", size = 207356 },
|
||||
{ url = "https://files.pythonhosted.org/packages/44/da/d49f19402240c93453f606e660a6676a2a1fbbaa6870cc23207790aa9697/coverage-7.6.9-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:61f70dc68bd36810972e55bbbe83674ea073dd1dcc121040a08cdf3416c5349c", size = 207614 },
|
||||
{ url = "https://files.pythonhosted.org/packages/da/e6/93bb9bf85497816082ec8da6124c25efa2052bd4c887dd3b317b91990c9e/coverage-7.6.9-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8a289d23d4c46f1a82d5db4abeb40b9b5be91731ee19a379d15790e53031c014", size = 240129 },
|
||||
{ url = "https://files.pythonhosted.org/packages/df/65/6a824b9406fe066835c1274a9949e06f084d3e605eb1a602727a27ec2fe3/coverage-7.6.9-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7e216d8044a356fc0337c7a2a0536d6de07888d7bcda76febcb8adc50bdbbd00", size = 237276 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9f/79/6c7a800913a9dd23ac8c8da133ebb556771a5a3d4df36b46767b1baffd35/coverage-7.6.9-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c026eb44f744acaa2bda7493dad903aa5bf5fc4f2554293a798d5606710055d", size = 239267 },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/e7/834d530293fdc8a63ba8ff70033d5182022e569eceb9aec7fc716b678a39/coverage-7.6.9-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e77363e8425325384f9d49272c54045bbed2f478e9dd698dbc65dbc37860eb0a", size = 238887 },
|
||||
{ url = "https://files.pythonhosted.org/packages/15/05/ec9d6080852984f7163c96984444e7cd98b338fd045b191064f943ee1c08/coverage-7.6.9-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:777abfab476cf83b5177b84d7486497e034eb9eaea0d746ce0c1268c71652077", size = 236970 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/d8/775937670b93156aec29f694ce37f56214ed7597e1a75b4083ee4c32121c/coverage-7.6.9-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:447af20e25fdbe16f26e84eb714ba21d98868705cb138252d28bc400381f6ffb", size = 238831 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/58/88551cb7fdd5ec98cb6044e8814e38583436b14040a5ece15349c44c8f7c/coverage-7.6.9-cp313-cp313-win32.whl", hash = "sha256:d872ec5aeb086cbea771c573600d47944eea2dcba8be5f3ee649bfe3cb8dc9ba", size = 210000 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/12/cfbf49b95120872785ff8d56ab1c7fe3970a65e35010c311d7dd35c5fd00/coverage-7.6.9-cp313-cp313-win_amd64.whl", hash = "sha256:fd1213c86e48dfdc5a0cc676551db467495a95a662d2396ecd58e719191446e1", size = 210753 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/68/c1cb31445599b04bde21cbbaa6d21b47c5823cdfef99eae470dfce49c35a/coverage-7.6.9-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:ba9e7484d286cd5a43744e5f47b0b3fb457865baf07bafc6bee91896364e1419", size = 208091 },
|
||||
{ url = "https://files.pythonhosted.org/packages/11/73/84b02c6b19c4a11eb2d5b5eabe926fb26c21c080e0852f5e5a4f01165f9e/coverage-7.6.9-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:e5ea1cf0872ee455c03e5674b5bca5e3e68e159379c1af0903e89f5eba9ccc3a", size = 208369 },
|
||||
{ url = "https://files.pythonhosted.org/packages/de/e0/ae5d878b72ff26df2e994a5c5b1c1f6a7507d976b23beecb1ed4c85411ef/coverage-7.6.9-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2d10e07aa2b91835d6abec555ec8b2733347956991901eea6ffac295f83a30e4", size = 251089 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/9c/0aaac011aef95a93ef3cb2fba3fde30bc7e68a6635199ed469b1f5ea355a/coverage-7.6.9-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:13a9e2d3ee855db3dd6ea1ba5203316a1b1fd8eaeffc37c5b54987e61e4194ae", size = 246806 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/19/4d5d3ae66938a7dcb2f58cef3fa5386f838f469575b0bb568c8cc9e3a33d/coverage-7.6.9-cp313-cp313t-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c38bf15a40ccf5619fa2fe8f26106c7e8e080d7760aeccb3722664c8656b030", size = 249164 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/0b/4ee8a7821f682af9ad440ae3c1e379da89a998883271f088102d7ca2473d/coverage-7.6.9-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:d5275455b3e4627c8e7154feaf7ee0743c2e7af82f6e3b561967b1cca755a0be", size = 248642 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/12/36ff1d52be18a16b4700f561852e7afd8df56363a5edcfb04cf26a0e19e0/coverage-7.6.9-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:8f8770dfc6e2c6a2d4569f411015c8d751c980d17a14b0530da2d7f27ffdd88e", size = 246516 },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/d0/8e258f6c3a527c1655602f4f576215e055ac704de2d101710a71a2affac2/coverage-7.6.9-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:8d2dfa71665a29b153a9681edb1c8d9c1ea50dfc2375fb4dac99ea7e21a0bcd9", size = 247783 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/0d/1e4a48d289429d38aae3babdfcadbf35ca36bdcf3efc8f09b550a845bdb5/coverage-7.6.9-cp313-cp313t-win32.whl", hash = "sha256:5e6b86b5847a016d0fbd31ffe1001b63355ed309651851295315031ea7eb5a9b", size = 210646 },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/74/b0729f196f328ac55e42b1e22ec2f16d8bcafe4b8158a26ec9f1cdd1d93e/coverage-7.6.9-cp313-cp313t-win_amd64.whl", hash = "sha256:97ddc94d46088304772d21b060041c97fc16bdda13c6c7f9d8fcd8d5ae0d8611", size = 211815 },
|
||||
]
|
||||
|
||||
[package.optional-dependencies]
|
||||
@ -340,31 +341,33 @@ toml = [
|
||||
|
||||
[[package]]
|
||||
name = "cryptography"
|
||||
version = "43.0.3"
|
||||
version = "44.0.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "cffi", marker = "platform_python_implementation != 'PyPy'" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/0d/05/07b55d1fa21ac18c3a8c79f764e2514e6f6a9698f1be44994f5adf0d29db/cryptography-43.0.3.tar.gz", hash = "sha256:315b9001266a492a6ff443b61238f956b214dbec9910a081ba5b6646a055a805", size = 686989 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/91/4c/45dfa6829acffa344e3967d6006ee4ae8be57af746ae2eba1c431949b32c/cryptography-44.0.0.tar.gz", hash = "sha256:cd4e834f340b4293430701e772ec543b0fbe6c2dea510a5286fe0acabe153a02", size = 710657 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/f3/01fdf26701a26f4b4dbc337a26883ad5bccaa6f1bbbdd29cd89e22f18a1c/cryptography-43.0.3-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bf7a1932ac4176486eab36a19ed4c0492da5d97123f1406cf15e41b05e787d2e", size = 6225303 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a3/01/4896f3d1b392025d4fcbecf40fdea92d3df8662123f6835d0af828d148fd/cryptography-43.0.3-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:63efa177ff54aec6e1c0aefaa1a241232dcd37413835a9b674b6e3f0ae2bfd3e", size = 3760905 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0a/be/f9a1f673f0ed4b7f6c643164e513dbad28dd4f2dcdf5715004f172ef24b6/cryptography-43.0.3-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e1ce50266f4f70bf41a2c6dc4358afadae90e2a1e5342d3c08883df1675374f", size = 3977271 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/49/80c3a7b5514d1b416d7350830e8c422a4d667b6d9b16a9392ebfd4a5388a/cryptography-43.0.3-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:443c4a81bb10daed9a8f334365fe52542771f25aedaf889fd323a853ce7377d6", size = 3746606 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/16/a28ddf78ac6e7e3f25ebcef69ab15c2c6be5ff9743dd0709a69a4f968472/cryptography-43.0.3-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:74f57f24754fe349223792466a709f8e0c093205ff0dca557af51072ff47ab18", size = 3986484 },
|
||||
{ url = "https://files.pythonhosted.org/packages/01/f5/69ae8da70c19864a32b0315049866c4d411cce423ec169993d0434218762/cryptography-43.0.3-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:9762ea51a8fc2a88b70cf2995e5675b38d93bf36bd67d91721c309df184f49bd", size = 3852131 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/db/e74911d95c040f9afd3612b1f732e52b3e517cb80de8bf183be0b7d413c6/cryptography-43.0.3-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:81ef806b1fef6b06dcebad789f988d3b37ccaee225695cf3e07648eee0fc6b73", size = 4075647 },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/48/7b6b190f1462818b324e674fa20d1d5ef3e24f2328675b9b16189cbf0b3c/cryptography-43.0.3-cp37-abi3-win32.whl", hash = "sha256:cbeb489927bd7af4aa98d4b261af9a5bc025bd87f0e3547e11584be9e9427be2", size = 2623873 },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/b1/0ebff61a004f7f89e7b65ca95f2f2375679d43d0290672f7713ee3162aff/cryptography-43.0.3-cp37-abi3-win_amd64.whl", hash = "sha256:f46304d6f0c6ab8e52770addfa2fc41e6629495548862279641972b6215451cd", size = 3068039 },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/d5/c8b32c047e2e81dd172138f772e81d852c51f0f2ad2ae8a24f1122e9e9a7/cryptography-43.0.3-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8ac43ae87929a5982f5948ceda07001ee5e83227fd69cf55b109144938d96984", size = 6222984 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/78/55356eb9075d0be6e81b59f45c7b48df87f76a20e73893872170471f3ee8/cryptography-43.0.3-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:846da004a5804145a5f441b8530b4bf35afbf7da70f82409f151695b127213d5", size = 3762968 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/2c/488776a3dc843f95f86d2f957ca0fc3407d0242b50bede7fad1e339be03f/cryptography-43.0.3-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0f996e7268af62598f2fc1204afa98a3b5712313a55c4c9d434aef49cadc91d4", size = 3977754 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/04/2345ca92f7a22f601a9c62961741ef7dd0127c39f7310dffa0041c80f16f/cryptography-43.0.3-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:f7b178f11ed3664fd0e995a47ed2b5ff0a12d893e41dd0494f406d1cf555cab7", size = 3749458 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ac/25/e715fa0bc24ac2114ed69da33adf451a38abb6f3f24ec207908112e9ba53/cryptography-43.0.3-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:c2e6fc39c4ab499049df3bdf567f768a723a5e8464816e8f009f121a5a9f4405", size = 3988220 },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/ce/b9c9ff56c7164d8e2edfb6c9305045fbc0df4508ccfdb13ee66eb8c95b0e/cryptography-43.0.3-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:e1be4655c7ef6e1bbe6b5d0403526601323420bcf414598955968c9ef3eb7d16", size = 3853898 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2a/33/b3682992ab2e9476b9c81fff22f02c8b0a1e6e1d49ee1750a67d85fd7ed2/cryptography-43.0.3-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:df6b6c6d742395dd77a23ea3728ab62f98379eff8fb61be2744d4679ab678f73", size = 4076592 },
|
||||
{ url = "https://files.pythonhosted.org/packages/81/1e/ffcc41b3cebd64ca90b28fd58141c5f68c83d48563c88333ab660e002cd3/cryptography-43.0.3-cp39-abi3-win32.whl", hash = "sha256:d56e96520b1020449bbace2b78b603442e7e378a9b3bd68de65c782db1507995", size = 2623145 },
|
||||
{ url = "https://files.pythonhosted.org/packages/87/5c/3dab83cc4aba1f4b0e733e3f0c3e7d4386440d660ba5b1e3ff995feb734d/cryptography-43.0.3-cp39-abi3-win_amd64.whl", hash = "sha256:0c580952eef9bf68c4747774cde7ec1d85a6e61de97281f2dba83c7d2c806362", size = 3068026 },
|
||||
{ url = "https://files.pythonhosted.org/packages/55/09/8cc67f9b84730ad330b3b72cf867150744bf07ff113cda21a15a1c6d2c7c/cryptography-44.0.0-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:84111ad4ff3f6253820e6d3e58be2cc2a00adb29335d4cacb5ab4d4d34f2a123", size = 6541833 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/5b/3759e30a103144e29632e7cb72aec28cedc79e514b2ea8896bb17163c19b/cryptography-44.0.0-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b15492a11f9e1b62ba9d73c210e2416724633167de94607ec6069ef724fad092", size = 3922710 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5f/58/3b14bf39f1a0cfd679e753e8647ada56cddbf5acebffe7db90e184c76168/cryptography-44.0.0-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:831c3c4d0774e488fdc83a1923b49b9957d33287de923d58ebd3cec47a0ae43f", size = 4137546 },
|
||||
{ url = "https://files.pythonhosted.org/packages/98/65/13d9e76ca19b0ba5603d71ac8424b5694415b348e719db277b5edc985ff5/cryptography-44.0.0-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:761817a3377ef15ac23cd7834715081791d4ec77f9297ee694ca1ee9c2c7e5eb", size = 3915420 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b1/07/40fe09ce96b91fc9276a9ad272832ead0fddedcba87f1190372af8e3039c/cryptography-44.0.0-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:3c672a53c0fb4725a29c303be906d3c1fa99c32f58abe008a82705f9ee96f40b", size = 4154498 },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/ea/af65619c800ec0a7e4034207aec543acdf248d9bffba0533342d1bd435e1/cryptography-44.0.0-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4ac4c9f37eba52cb6fbeaf5b59c152ea976726b865bd4cf87883a7e7006cc543", size = 3932569 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/af/d1deb0c04d59612e3d5e54203159e284d3e7a6921e565bb0eeb6269bdd8a/cryptography-44.0.0-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ed3534eb1090483c96178fcb0f8893719d96d5274dfde98aa6add34614e97c8e", size = 4016721 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bd/69/7ca326c55698d0688db867795134bdfac87136b80ef373aaa42b225d6dd5/cryptography-44.0.0-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:f3f6fdfa89ee2d9d496e2c087cebef9d4fcbb0ad63c40e821b39f74bf48d9c5e", size = 4240915 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/d4/cae11bf68c0f981e0413906c6dd03ae7fa864347ed5fac40021df1ef467c/cryptography-44.0.0-cp37-abi3-win32.whl", hash = "sha256:eb33480f1bad5b78233b0ad3e1b0be21e8ef1da745d8d2aecbb20671658b9053", size = 2757925 },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/b1/50d7739254d2002acae64eed4fc43b24ac0cc44bf0a0d388d1ca06ec5bb1/cryptography-44.0.0-cp37-abi3-win_amd64.whl", hash = "sha256:abc998e0c0eee3c8a1904221d3f67dcfa76422b23620173e28c11d3e626c21bd", size = 3202055 },
|
||||
{ url = "https://files.pythonhosted.org/packages/11/18/61e52a3d28fc1514a43b0ac291177acd1b4de00e9301aaf7ef867076ff8a/cryptography-44.0.0-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:660cb7312a08bc38be15b696462fa7cc7cd85c3ed9c576e81f4dc4d8b2b31591", size = 6542801 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/07/5f165b6c65696ef75601b781a280fc3b33f1e0cd6aa5a92d9fb96c410e97/cryptography-44.0.0-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1923cb251c04be85eec9fda837661c67c1049063305d6be5721643c22dd4e2b7", size = 3922613 },
|
||||
{ url = "https://files.pythonhosted.org/packages/28/34/6b3ac1d80fc174812486561cf25194338151780f27e438526f9c64e16869/cryptography-44.0.0-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:404fdc66ee5f83a1388be54300ae978b2efd538018de18556dde92575e05defc", size = 4137925 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/c7/c656eb08fd22255d21bc3129625ed9cd5ee305f33752ef2278711b3fa98b/cryptography-44.0.0-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:c5eb858beed7835e5ad1faba59e865109f3e52b3783b9ac21e7e47dc5554e289", size = 3915417 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/82/72403624f197af0db6bac4e58153bc9ac0e6020e57234115db9596eee85d/cryptography-44.0.0-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:f53c2c87e0fb4b0c00fa9571082a057e37690a8f12233306161c8f4b819960b7", size = 4155160 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a2/cd/2f3c440913d4329ade49b146d74f2e9766422e1732613f57097fea61f344/cryptography-44.0.0-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:9e6fc8a08e116fb7c7dd1f040074c9d7b51d74a8ea40d4df2fc7aa08b76b9e6c", size = 3932331 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/df/8be88797f0a1cca6e255189a57bb49237402b1880d6e8721690c5603ac23/cryptography-44.0.0-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:d2436114e46b36d00f8b72ff57e598978b37399d2786fd39793c36c6d5cb1c64", size = 4017372 },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/36/5ccc376f025a834e72b8e52e18746b927f34e4520487098e283a719c205e/cryptography-44.0.0-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a01956ddfa0a6790d594f5b34fc1bfa6098aca434696a03cfdbe469b8ed79285", size = 4239657 },
|
||||
{ url = "https://files.pythonhosted.org/packages/46/b0/f4f7d0d0bcfbc8dd6296c1449be326d04217c57afb8b2594f017eed95533/cryptography-44.0.0-cp39-abi3-win32.whl", hash = "sha256:eca27345e1214d1b9f9490d200f9db5a874479be914199194e746c893788d417", size = 2758672 },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/9b/443270b9210f13f6ef240eff73fd32e02d381e7103969dc66ce8e89ee901/cryptography-44.0.0-cp39-abi3-win_amd64.whl", hash = "sha256:708ee5f1bafe76d041b53a4f95eb28cdeb8d18da17e597d46d7833ee59b97ede", size = 3202071 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -700,30 +703,30 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "mypy"
|
||||
version = "1.13.0"
|
||||
version = "1.14.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "mypy-extensions" },
|
||||
{ name = "typing-extensions" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/e8/21/7e9e523537991d145ab8a0a2fd98548d67646dc2aaaf6091c31ad883e7c1/mypy-1.13.0.tar.gz", hash = "sha256:0291a61b6fbf3e6673e3405cfcc0e7650bebc7939659fdca2702958038bd835e", size = 3152532 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/8c/7b/08046ef9330735f536a09a2e31b00f42bccdb2795dcd979636ba43bb2d63/mypy-1.14.0.tar.gz", hash = "sha256:822dbd184d4a9804df5a7d5335a68cf7662930e70b8c1bc976645d1509f9a9d6", size = 3215684 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/19/de0822609e5b93d02579075248c7aa6ceaddcea92f00bf4ea8e4c22e3598/mypy-1.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:581665e6f3a8a9078f28d5502f4c334c0c8d802ef55ea0e7276a6e409bc0d82d", size = 10939027 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/71/6950fcc6ca84179137e4cbf7cf41e6b68b4a339a1f5d3e954f8c34e02d66/mypy-1.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3ddb5b9bf82e05cc9a627e84707b528e5c7caaa1c55c69e175abb15a761cec2d", size = 10108699 },
|
||||
{ url = "https://files.pythonhosted.org/packages/26/50/29d3e7dd166e74dc13d46050b23f7d6d7533acf48f5217663a3719db024e/mypy-1.13.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:20c7ee0bc0d5a9595c46f38beb04201f2620065a93755704e141fcac9f59db2b", size = 12506263 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/1d/676e76f07f7d5ddcd4227af3938a9c9640f293b7d8a44dd4ff41d4db25c1/mypy-1.13.0-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:3790ded76f0b34bc9c8ba4def8f919dd6a46db0f5a6610fb994fe8efdd447f73", size = 12984688 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/03/5a85a30ae5407b1d28fab51bd3e2103e52ad0918d1e68f02a7778669a307/mypy-1.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:51f869f4b6b538229c1d1bcc1dd7d119817206e2bc54e8e374b3dfa202defcca", size = 9626811 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fb/31/c526a7bd2e5c710ae47717c7a5f53f616db6d9097caf48ad650581e81748/mypy-1.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:5c7051a3461ae84dfb5dd15eff5094640c61c5f22257c8b766794e6dd85e72d5", size = 11077900 },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/67/b7419c6b503679d10bd26fc67529bc6a1f7a5f220bbb9f292dc10d33352f/mypy-1.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:39bb21c69a5d6342f4ce526e4584bc5c197fd20a60d14a8624d8743fffb9472e", size = 10074818 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ba/07/37d67048786ae84e6612575e173d713c9a05d0ae495dde1e68d972207d98/mypy-1.13.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:164f28cb9d6367439031f4c81e84d3ccaa1e19232d9d05d37cb0bd880d3f93c2", size = 12589275 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/17/b1018c6bb3e9f1ce3956722b3bf91bff86c1cefccca71cec05eae49d6d41/mypy-1.13.0-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:a4c1bfcdbce96ff5d96fc9b08e3831acb30dc44ab02671eca5953eadad07d6d0", size = 13037783 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cb/32/cd540755579e54a88099aee0287086d996f5a24281a673f78a0e14dba150/mypy-1.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:a0affb3a79a256b4183ba09811e3577c5163ed06685e4d4b46429a271ba174d2", size = 9726197 },
|
||||
{ url = "https://files.pythonhosted.org/packages/11/bb/ab4cfdc562cad80418f077d8be9b4491ee4fb257440da951b85cbb0a639e/mypy-1.13.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:a7b44178c9760ce1a43f544e595d35ed61ac2c3de306599fa59b38a6048e1aa7", size = 11069721 },
|
||||
{ url = "https://files.pythonhosted.org/packages/59/3b/a393b1607cb749ea2c621def5ba8c58308ff05e30d9dbdc7c15028bca111/mypy-1.13.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:5d5092efb8516d08440e36626f0153b5006d4088c1d663d88bf79625af3d1d62", size = 10063996 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d1/1f/6b76be289a5a521bb1caedc1f08e76ff17ab59061007f201a8a18cc514d1/mypy-1.13.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:de2904956dac40ced10931ac967ae63c5089bd498542194b436eb097a9f77bc8", size = 12584043 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a6/83/5a85c9a5976c6f96e3a5a7591aa28b4a6ca3a07e9e5ba0cec090c8b596d6/mypy-1.13.0-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:7bfd8836970d33c2105562650656b6846149374dc8ed77d98424b40b09340ba7", size = 13036996 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/59/c39a6f752f1f893fccbcf1bdd2aca67c79c842402b5283563d006a67cf76/mypy-1.13.0-cp313-cp313-win_amd64.whl", hash = "sha256:9f73dba9ec77acb86457a8fc04b5239822df0c14a082564737833d2963677dbc", size = 9737709 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/86/72ce7f57431d87a7ff17d442f521146a6585019eb8f4f31b7c02801f78ad/mypy-1.13.0-py3-none-any.whl", hash = "sha256:9c250883f9fd81d212e0952c92dbfcc96fc237f4b7c92f56ac81fd48460b3e5a", size = 2647043 },
|
||||
{ url = "https://files.pythonhosted.org/packages/34/c1/b9dd3e955953aec1c728992545b7877c9f6fa742a623ce4c200da0f62540/mypy-1.14.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:6e73c8a154eed31db3445fe28f63ad2d97b674b911c00191416cf7f6459fd49a", size = 11121032 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ee/96/c52d5d516819ab95bf41f4a1ada828a3decc302f8c152ff4fc5feb0e4529/mypy-1.14.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:273e70fcb2e38c5405a188425aa60b984ffdcef65d6c746ea5813024b68c73dc", size = 10286294 },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/2c/3dbe51877a24daa467f8d8631f9ffd1aabbf0f6d9367a01c44a59df81fe0/mypy-1.14.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1daca283d732943731a6a9f20fdbcaa927f160bc51602b1d4ef880a6fb252015", size = 12746528 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/a8/eb20cde4ba9c4c3e20d958918a7c5d92210f4d1a0200c27de9a641f70996/mypy-1.14.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7e68047bedb04c1c25bba9901ea46ff60d5eaac2d71b1f2161f33107e2b368eb", size = 12883489 },
|
||||
{ url = "https://files.pythonhosted.org/packages/91/17/a1fc6c70f31d52c99299320cf81c3cb2c6b91ec7269414e0718a6d138e34/mypy-1.14.0-cp311-cp311-win_amd64.whl", hash = "sha256:7a52f26b9c9b1664a60d87675f3bae00b5c7f2806e0c2800545a32c325920bcc", size = 9780113 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/d8/0e72175ee0253217f5c44524f5e95251c02e95ba9749fb87b0e2074d203a/mypy-1.14.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d5326ab70a6db8e856d59ad4cb72741124950cbbf32e7b70e30166ba7bbf61dd", size = 11269011 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/6d/4ea13839dabe5db588dc6a1b766da16f420d33cf118a7b7172cdf6c7fcb2/mypy-1.14.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf4ec4980bec1e0e24e5075f449d014011527ae0055884c7e3abc6a99cd2c7f1", size = 10253076 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3e/38/7db2c5d0f4d290e998f7a52b2e2616c7bbad96b8e04278ab09d11978a29e/mypy-1.14.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:390dfb898239c25289495500f12fa73aa7f24a4c6d90ccdc165762462b998d63", size = 12862786 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/4b/62d59c801b34141040989949c2b5c157d0408b45357335d3ec5b2845b0f6/mypy-1.14.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:7e026d55ddcd76e29e87865c08cbe2d0104e2b3153a523c529de584759379d3d", size = 12971568 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/9c/e0f281b32d70c87b9e4d2939e302b1ff77ada4d7b0f2fb32890c144bc1d6/mypy-1.14.0-cp312-cp312-win_amd64.whl", hash = "sha256:585ed36031d0b3ee362e5107ef449a8b5dfd4e9c90ccbe36414ee405ee6b32ba", size = 9879477 },
|
||||
{ url = "https://files.pythonhosted.org/packages/13/33/8380efd0ebdfdfac7fc0bf065f03a049800ca1e6c296ec1afc634340d992/mypy-1.14.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:e9f6f4c0b27401d14c483c622bc5105eff3911634d576bbdf6695b9a7c1ba741", size = 11251509 },
|
||||
{ url = "https://files.pythonhosted.org/packages/15/6d/4e1c21c60fee11af7d8e4f2902a29886d1387d6a836be16229eb3982a963/mypy-1.14.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:56b2280cedcb312c7a79f5001ae5325582d0d339bce684e4a529069d0e7ca1e7", size = 10244282 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8b/cf/7a8ae5c0161edae15d25c2c67c68ce8b150cbdc45aefc13a8be271ee80b2/mypy-1.14.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:342de51c48bab326bfc77ce056ba08c076d82ce4f5a86621f972ed39970f94d8", size = 12867676 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/d0/71f7bbdcc7cfd0f2892db5b13b1e8857673f2cc9e0c30e3e4340523dc186/mypy-1.14.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:00df23b42e533e02a6f0055e54de9a6ed491cd8b7ea738647364fd3a39ea7efc", size = 12964189 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/40/fb4ad65d6d5f8c51396ecf6305ec0269b66013a5bf02d0e9528053640b4a/mypy-1.14.0-cp313-cp313-win_amd64.whl", hash = "sha256:e8c8387e5d9dff80e7daf961df357c80e694e942d9755f3ad77d69b0957b8e3f", size = 9888247 },
|
||||
{ url = "https://files.pythonhosted.org/packages/39/32/0214608af400cdf8f5102144bb8af10d880675c65ed0b58f7e0e77175d50/mypy-1.14.0-py3-none-any.whl", hash = "sha256:2238d7f93fc4027ed1efc944507683df3ba406445a2b6c96e79666a045aadfab", size = 2752803 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -870,59 +873,59 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "propcache"
|
||||
version = "0.2.0"
|
||||
version = "0.2.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/a9/4d/5e5a60b78dbc1d464f8a7bbaeb30957257afdc8512cbb9dfd5659304f5cd/propcache-0.2.0.tar.gz", hash = "sha256:df81779732feb9d01e5d513fad0122efb3d53bbc75f61b2a4f29a020bc985e70", size = 40951 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/20/c8/2a13f78d82211490855b2fb303b6721348d0787fdd9a12ac46d99d3acde1/propcache-0.2.1.tar.gz", hash = "sha256:3f77ce728b19cb537714499928fe800c3dda29e8d9428778fc7c186da4c09a64", size = 41735 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/e0/1c/71eec730e12aec6511e702ad0cd73c2872eccb7cad39de8ba3ba9de693ef/propcache-0.2.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:63f13bf09cc3336eb04a837490b8f332e0db41da66995c9fd1ba04552e516354", size = 80811 },
|
||||
{ url = "https://files.pythonhosted.org/packages/89/c3/7e94009f9a4934c48a371632197406a8860b9f08e3f7f7d922ab69e57a41/propcache-0.2.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:608cce1da6f2672a56b24a015b42db4ac612ee709f3d29f27a00c943d9e851de", size = 46365 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c0/1d/c700d16d1d6903aeab28372fe9999762f074b80b96a0ccc953175b858743/propcache-0.2.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:466c219deee4536fbc83c08d09115249db301550625c7fef1c5563a584c9bc87", size = 45602 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/5e/4a3e96380805bf742712e39a4534689f4cddf5fa2d3a93f22e9fd8001b23/propcache-0.2.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fc2db02409338bf36590aa985a461b2c96fce91f8e7e0f14c50c5fcc4f229016", size = 236161 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/85/90132481183d1436dff6e29f4fa81b891afb6cb89a7306f32ac500a25932/propcache-0.2.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:a6ed8db0a556343d566a5c124ee483ae113acc9a557a807d439bcecc44e7dfbb", size = 244938 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4a/89/c893533cb45c79c970834274e2d0f6d64383ec740be631b6a0a1d2b4ddc0/propcache-0.2.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:91997d9cb4a325b60d4e3f20967f8eb08dfcb32b22554d5ef78e6fd1dda743a2", size = 243576 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/56/98c2054c8526331a05f205bf45cbb2cda4e58e56df70e76d6a509e5d6ec6/propcache-0.2.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4c7dde9e533c0a49d802b4f3f218fa9ad0a1ce21f2c2eb80d5216565202acab4", size = 236011 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2d/0c/8b8b9f8a6e1abd869c0fa79b907228e7abb966919047d294ef5df0d136cf/propcache-0.2.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffcad6c564fe6b9b8916c1aefbb37a362deebf9394bd2974e9d84232e3e08504", size = 224834 },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/bb/397d05a7298b7711b90e13108db697732325cafdcd8484c894885c1bf109/propcache-0.2.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:97a58a28bcf63284e8b4d7b460cbee1edaab24634e82059c7b8c09e65284f178", size = 224946 },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/19/4fc08dac19297ac58135c03770b42377be211622fd0147f015f78d47cd31/propcache-0.2.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:945db8ee295d3af9dbdbb698cce9bbc5c59b5c3fe328bbc4387f59a8a35f998d", size = 217280 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/76/c79276a43df2096ce2aba07ce47576832b1174c0c480fe6b04bd70120e59/propcache-0.2.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39e104da444a34830751715f45ef9fc537475ba21b7f1f5b0f4d71a3b60d7fe2", size = 220088 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c3/9a/8a8cf428a91b1336b883f09c8b884e1734c87f724d74b917129a24fe2093/propcache-0.2.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c5ecca8f9bab618340c8e848d340baf68bcd8ad90a8ecd7a4524a81c1764b3db", size = 233008 },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/7b/768a8969abd447d5f0f3333df85c6a5d94982a1bc9a89c53c154bf7a8b11/propcache-0.2.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c436130cc779806bdf5d5fae0d848713105472b8566b75ff70048c47d3961c5b", size = 237719 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/0d/e5d68ccc7976ef8b57d80613ac07bbaf0614d43f4750cf953f0168ef114f/propcache-0.2.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:191db28dc6dcd29d1a3e063c3be0b40688ed76434622c53a284e5427565bbd9b", size = 227729 },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/64/17eb2796e2d1c3d0c431dc5f40078d7282f4645af0bb4da9097fbb628c6c/propcache-0.2.0-cp311-cp311-win32.whl", hash = "sha256:5f2564ec89058ee7c7989a7b719115bdfe2a2fb8e7a4543b8d1c0cc4cf6478c1", size = 40473 },
|
||||
{ url = "https://files.pythonhosted.org/packages/83/c5/e89fc428ccdc897ade08cd7605f174c69390147526627a7650fb883e0cd0/propcache-0.2.0-cp311-cp311-win_amd64.whl", hash = "sha256:6e2e54267980349b723cff366d1e29b138b9a60fa376664a157a342689553f71", size = 44921 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/46/a41ca1097769fc548fc9216ec4c1471b772cc39720eb47ed7e38ef0006a9/propcache-0.2.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:2ee7606193fb267be4b2e3b32714f2d58cad27217638db98a60f9efb5efeccc2", size = 80800 },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/4f/93df46aab9cc473498ff56be39b5f6ee1e33529223d7a4d8c0a6101a9ba2/propcache-0.2.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:91ee8fc02ca52e24bcb77b234f22afc03288e1dafbb1f88fe24db308910c4ac7", size = 46443 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/17/308acc6aee65d0f9a8375e36c4807ac6605d1f38074b1581bd4042b9fb37/propcache-0.2.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2e900bad2a8456d00a113cad8c13343f3b1f327534e3589acc2219729237a2e8", size = 45676 },
|
||||
{ url = "https://files.pythonhosted.org/packages/65/44/626599d2854d6c1d4530b9a05e7ff2ee22b790358334b475ed7c89f7d625/propcache-0.2.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f52a68c21363c45297aca15561812d542f8fc683c85201df0bebe209e349f793", size = 246191 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f2/df/5d996d7cb18df076debae7d76ac3da085c0575a9f2be6b1f707fe227b54c/propcache-0.2.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1e41d67757ff4fbc8ef2af99b338bfb955010444b92929e9e55a6d4dcc3c4f09", size = 251791 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2e/6d/9f91e5dde8b1f662f6dd4dff36098ed22a1ef4e08e1316f05f4758f1576c/propcache-0.2.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a64e32f8bd94c105cc27f42d3b658902b5bcc947ece3c8fe7bc1b05982f60e89", size = 253434 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/e9/1b54b7e26f50b3e0497cd13d3483d781d284452c2c50dd2a615a92a087a3/propcache-0.2.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55346705687dbd7ef0d77883ab4f6fabc48232f587925bdaf95219bae072491e", size = 248150 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a7/ef/a35bf191c8038fe3ce9a414b907371c81d102384eda5dbafe6f4dce0cf9b/propcache-0.2.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:00181262b17e517df2cd85656fcd6b4e70946fe62cd625b9d74ac9977b64d8d9", size = 233568 },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/d9/d00bb9277a9165a5e6d60f2142cd1a38a750045c9c12e47ae087f686d781/propcache-0.2.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6994984550eaf25dd7fc7bd1b700ff45c894149341725bb4edc67f0ffa94efa4", size = 229874 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/78/c123cf22469bdc4b18efb78893e69c70a8b16de88e6160b69ca6bdd88b5d/propcache-0.2.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:56295eb1e5f3aecd516d91b00cfd8bf3a13991de5a479df9e27dd569ea23959c", size = 225857 },
|
||||
{ url = "https://files.pythonhosted.org/packages/31/1b/fd6b2f1f36d028820d35475be78859d8c89c8f091ad30e377ac49fd66359/propcache-0.2.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:439e76255daa0f8151d3cb325f6dd4a3e93043e6403e6491813bcaaaa8733887", size = 227604 },
|
||||
{ url = "https://files.pythonhosted.org/packages/99/36/b07be976edf77a07233ba712e53262937625af02154353171716894a86a6/propcache-0.2.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f6475a1b2ecb310c98c28d271a30df74f9dd436ee46d09236a6b750a7599ce57", size = 238430 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0d/64/5822f496c9010e3966e934a011ac08cac8734561842bc7c1f65586e0683c/propcache-0.2.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:3444cdba6628accf384e349014084b1cacd866fbb88433cd9d279d90a54e0b23", size = 244814 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/bd/8657918a35d50b18a9e4d78a5df7b6c82a637a311ab20851eef4326305c1/propcache-0.2.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:4a9d9b4d0a9b38d1c391bb4ad24aa65f306c6f01b512e10a8a34a2dc5675d348", size = 235922 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/6f/ec0095e1647b4727db945213a9f395b1103c442ef65e54c62e92a72a3f75/propcache-0.2.0-cp312-cp312-win32.whl", hash = "sha256:69d3a98eebae99a420d4b28756c8ce6ea5a29291baf2dc9ff9414b42676f61d5", size = 40177 },
|
||||
{ url = "https://files.pythonhosted.org/packages/20/a2/bd0896fdc4f4c1db46d9bc361c8c79a9bf08ccc08ba054a98e38e7ba1557/propcache-0.2.0-cp312-cp312-win_amd64.whl", hash = "sha256:ad9c9b99b05f163109466638bd30ada1722abb01bbb85c739c50b6dc11f92dc3", size = 44446 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/a7/5f37b69197d4f558bfef5b4bceaff7c43cc9b51adf5bd75e9081d7ea80e4/propcache-0.2.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ecddc221a077a8132cf7c747d5352a15ed763b674c0448d811f408bf803d9ad7", size = 78120 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/cd/48ab2b30a6b353ecb95a244915f85756d74f815862eb2ecc7a518d565b48/propcache-0.2.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:0e53cb83fdd61cbd67202735e6a6687a7b491c8742dfc39c9e01e80354956763", size = 45127 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a5/ba/0a1ef94a3412aab057bd996ed5f0ac7458be5bf469e85c70fa9ceb43290b/propcache-0.2.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:92fe151145a990c22cbccf9ae15cae8ae9eddabfc949a219c9f667877e40853d", size = 44419 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/6c/ca70bee4f22fa99eacd04f4d2f1699be9d13538ccf22b3169a61c60a27fa/propcache-0.2.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d6a21ef516d36909931a2967621eecb256018aeb11fc48656e3257e73e2e247a", size = 229611 },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/70/47b872a263e8511ca33718d96a10c17d3c853aefadeb86dc26e8421184b9/propcache-0.2.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3f88a4095e913f98988f5b338c1d4d5d07dbb0b6bad19892fd447484e483ba6b", size = 234005 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/be/3b0ab8c84a22e4a3224719099c1229ddfdd8a6a1558cf75cb55ee1e35c25/propcache-0.2.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5a5b3bb545ead161be780ee85a2b54fdf7092815995661947812dde94a40f6fb", size = 237270 },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/d8/f071bb000d4b8f851d312c3c75701e586b3f643fe14a2e3409b1b9ab3936/propcache-0.2.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:67aeb72e0f482709991aa91345a831d0b707d16b0257e8ef88a2ad246a7280bf", size = 231877 },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/e7/57a035a1359e542bbb0a7df95aad6b9871ebee6dce2840cb157a415bd1f3/propcache-0.2.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:3c997f8c44ec9b9b0bcbf2d422cc00a1d9b9c681f56efa6ca149a941e5560da2", size = 217848 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f0/93/d1dea40f112ec183398fb6c42fde340edd7bab202411c4aa1a8289f461b6/propcache-0.2.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:2a66df3d4992bc1d725b9aa803e8c5a66c010c65c741ad901e260ece77f58d2f", size = 216987 },
|
||||
{ url = "https://files.pythonhosted.org/packages/62/4c/877340871251145d3522c2b5d25c16a1690ad655fbab7bb9ece6b117e39f/propcache-0.2.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:3ebbcf2a07621f29638799828b8d8668c421bfb94c6cb04269130d8de4fb7136", size = 212451 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/bb/a91b72efeeb42906ef58ccf0cdb87947b54d7475fee3c93425d732f16a61/propcache-0.2.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:1235c01ddaa80da8235741e80815ce381c5267f96cc49b1477fdcf8c047ef325", size = 212879 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9b/7f/ee7fea8faac57b3ec5d91ff47470c6c5d40d7f15d0b1fccac806348fa59e/propcache-0.2.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:3947483a381259c06921612550867b37d22e1df6d6d7e8361264b6d037595f44", size = 222288 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/d7/acd67901c43d2e6b20a7a973d9d5fd543c6e277af29b1eb0e1f7bd7ca7d2/propcache-0.2.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:d5bed7f9805cc29c780f3aee05de3262ee7ce1f47083cfe9f77471e9d6777e83", size = 228257 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8d/6f/6272ecc7a8daad1d0754cfc6c8846076a8cb13f810005c79b15ce0ef0cf2/propcache-0.2.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e4a91d44379f45f5e540971d41e4626dacd7f01004826a18cb048e7da7e96544", size = 221075 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7c/bd/c7a6a719a6b3dd8b3aeadb3675b5783983529e4a3185946aa444d3e078f6/propcache-0.2.0-cp313-cp313-win32.whl", hash = "sha256:f902804113e032e2cdf8c71015651c97af6418363bea8d78dc0911d56c335032", size = 39654 },
|
||||
{ url = "https://files.pythonhosted.org/packages/88/e7/0eef39eff84fa3e001b44de0bd41c7c0e3432e7648ffd3d64955910f002d/propcache-0.2.0-cp313-cp313-win_amd64.whl", hash = "sha256:8f188cfcc64fb1266f4684206c9de0e80f54622c3f22a910cbd200478aeae61e", size = 43705 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3d/b6/e6d98278f2d49b22b4d033c9f792eda783b9ab2094b041f013fc69bcde87/propcache-0.2.0-py3-none-any.whl", hash = "sha256:2ccc28197af5313706511fab3a8b66dcd6da067a1331372c82ea1cb74285e036", size = 11603 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bc/0f/2913b6791ebefb2b25b4efd4bb2299c985e09786b9f5b19184a88e5778dd/propcache-0.2.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ffc3cca89bb438fb9c95c13fc874012f7b9466b89328c3c8b1aa93cdcfadd16", size = 79297 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/73/af2053aeccd40b05d6e19058419ac77674daecdd32478088b79375b9ab54/propcache-0.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f174bbd484294ed9fdf09437f889f95807e5f229d5d93588d34e92106fbf6717", size = 45611 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/09/8386115ba7775ea3b9537730e8cf718d83bbf95bffe30757ccf37ec4e5da/propcache-0.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:70693319e0b8fd35dd863e3e29513875eb15c51945bf32519ef52927ca883bc3", size = 45146 },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/7a/793aa12f0537b2e520bf09f4c6833706b63170a211ad042ca71cbf79d9cb/propcache-0.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b480c6a4e1138e1aa137c0079b9b6305ec6dcc1098a8ca5196283e8a49df95a9", size = 232136 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/38/b921b3168d72111769f648314100558c2ea1d52eb3d1ba7ea5c4aa6f9848/propcache-0.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d27b84d5880f6d8aa9ae3edb253c59d9f6642ffbb2c889b78b60361eed449787", size = 239706 },
|
||||
{ url = "https://files.pythonhosted.org/packages/14/29/4636f500c69b5edea7786db3c34eb6166f3384b905665ce312a6e42c720c/propcache-0.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:857112b22acd417c40fa4595db2fe28ab900c8c5fe4670c7989b1c0230955465", size = 238531 },
|
||||
{ url = "https://files.pythonhosted.org/packages/85/14/01fe53580a8e1734ebb704a3482b7829a0ef4ea68d356141cf0994d9659b/propcache-0.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cf6c4150f8c0e32d241436526f3c3f9cbd34429492abddbada2ffcff506c51af", size = 231063 },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/5c/1d961299f3c3b8438301ccfbff0143b69afcc30c05fa28673cface692305/propcache-0.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:66d4cfda1d8ed687daa4bc0274fcfd5267873db9a5bc0418c2da19273040eeb7", size = 220134 },
|
||||
{ url = "https://files.pythonhosted.org/packages/00/d0/ed735e76db279ba67a7d3b45ba4c654e7b02bc2f8050671ec365d8665e21/propcache-0.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c2f992c07c0fca81655066705beae35fc95a2fa7366467366db627d9f2ee097f", size = 220009 },
|
||||
{ url = "https://files.pythonhosted.org/packages/75/90/ee8fab7304ad6533872fee982cfff5a53b63d095d78140827d93de22e2d4/propcache-0.2.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:4a571d97dbe66ef38e472703067021b1467025ec85707d57e78711c085984e54", size = 212199 },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/ec/977ffaf1664f82e90737275873461695d4c9407d52abc2f3c3e24716da13/propcache-0.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:bb6178c241278d5fe853b3de743087be7f5f4c6f7d6d22a3b524d323eecec505", size = 214827 },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/48/031fb87ab6081764054821a71b71942161619549396224cbb242922525e8/propcache-0.2.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:ad1af54a62ffe39cf34db1aa6ed1a1873bd548f6401db39d8e7cd060b9211f82", size = 228009 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/06/ef1390f2524850838f2390421b23a8b298f6ce3396a7cc6d39dedd4047b0/propcache-0.2.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e7048abd75fe40712005bcfc06bb44b9dfcd8e101dda2ecf2f5aa46115ad07ca", size = 231638 },
|
||||
{ url = "https://files.pythonhosted.org/packages/38/2a/101e6386d5a93358395da1d41642b79c1ee0f3b12e31727932b069282b1d/propcache-0.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:160291c60081f23ee43d44b08a7e5fb76681221a8e10b3139618c5a9a291b84e", size = 222788 },
|
||||
{ url = "https://files.pythonhosted.org/packages/db/81/786f687951d0979007e05ad9346cd357e50e3d0b0f1a1d6074df334b1bbb/propcache-0.2.1-cp311-cp311-win32.whl", hash = "sha256:819ce3b883b7576ca28da3861c7e1a88afd08cc8c96908e08a3f4dd64a228034", size = 40170 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/59/7cc7037b295d5772eceb426358bb1b86e6cab4616d971bd74275395d100d/propcache-0.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:edc9fc7051e3350643ad929df55c451899bb9ae6d24998a949d2e4c87fb596d3", size = 44404 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4c/28/1d205fe49be8b1b4df4c50024e62480a442b1a7b818e734308bb0d17e7fb/propcache-0.2.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:081a430aa8d5e8876c6909b67bd2d937bfd531b0382d3fdedb82612c618bc41a", size = 79588 },
|
||||
{ url = "https://files.pythonhosted.org/packages/21/ee/fc4d893f8d81cd4971affef2a6cb542b36617cd1d8ce56b406112cb80bf7/propcache-0.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d2ccec9ac47cf4e04897619c0e0c1a48c54a71bdf045117d3a26f80d38ab1fb0", size = 45825 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4a/de/bbe712f94d088da1d237c35d735f675e494a816fd6f54e9db2f61ef4d03f/propcache-0.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:14d86fe14b7e04fa306e0c43cdbeebe6b2c2156a0c9ce56b815faacc193e320d", size = 45357 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7f/14/7ae06a6cf2a2f1cb382586d5a99efe66b0b3d0c6f9ac2f759e6f7af9d7cf/propcache-0.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:049324ee97bb67285b49632132db351b41e77833678432be52bdd0289c0e05e4", size = 241869 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/59/227a78be960b54a41124e639e2c39e8807ac0c751c735a900e21315f8c2b/propcache-0.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1cd9a1d071158de1cc1c71a26014dcdfa7dd3d5f4f88c298c7f90ad6f27bb46d", size = 247884 },
|
||||
{ url = "https://files.pythonhosted.org/packages/84/58/f62b4ffaedf88dc1b17f04d57d8536601e4e030feb26617228ef930c3279/propcache-0.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98110aa363f1bb4c073e8dcfaefd3a5cea0f0834c2aab23dda657e4dab2f53b5", size = 248486 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/07/ebe102777a830bca91bbb93e3479cd34c2ca5d0361b83be9dbd93104865e/propcache-0.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:647894f5ae99c4cf6bb82a1bb3a796f6e06af3caa3d32e26d2350d0e3e3faf24", size = 243649 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/bc/4f7aba7f08f520376c4bb6a20b9a981a581b7f2e385fa0ec9f789bb2d362/propcache-0.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:bfd3223c15bebe26518d58ccf9a39b93948d3dcb3e57a20480dfdd315356baff", size = 229103 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fe/d5/04ac9cd4e51a57a96f78795e03c5a0ddb8f23ec098b86f92de028d7f2a6b/propcache-0.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:d71264a80f3fcf512eb4f18f59423fe82d6e346ee97b90625f283df56aee103f", size = 226607 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e3/f0/24060d959ea41d7a7cc7fdbf68b31852331aabda914a0c63bdb0e22e96d6/propcache-0.2.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:e73091191e4280403bde6c9a52a6999d69cdfde498f1fdf629105247599b57ec", size = 221153 },
|
||||
{ url = "https://files.pythonhosted.org/packages/77/a7/3ac76045a077b3e4de4859a0753010765e45749bdf53bd02bc4d372da1a0/propcache-0.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3935bfa5fede35fb202c4b569bb9c042f337ca4ff7bd540a0aa5e37131659348", size = 222151 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e7/af/5e29da6f80cebab3f5a4dcd2a3240e7f56f2c4abf51cbfcc99be34e17f0b/propcache-0.2.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:f508b0491767bb1f2b87fdfacaba5f7eddc2f867740ec69ece6d1946d29029a6", size = 233812 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8c/89/ebe3ad52642cc5509eaa453e9f4b94b374d81bae3265c59d5c2d98efa1b4/propcache-0.2.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1672137af7c46662a1c2be1e8dc78cb6d224319aaa40271c9257d886be4363a6", size = 238829 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e9/2f/6b32f273fa02e978b7577159eae7471b3cfb88b48563b1c2578b2d7ca0bb/propcache-0.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b74c261802d3d2b85c9df2dfb2fa81b6f90deeef63c2db9f0e029a3cac50b518", size = 230704 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/2e/f40ae6ff5624a5f77edd7b8359b208b5455ea113f68309e2b00a2e1426b6/propcache-0.2.1-cp312-cp312-win32.whl", hash = "sha256:d09c333d36c1409d56a9d29b3a1b800a42c76a57a5a8907eacdbce3f18768246", size = 40050 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/77/a92c3ef994e47180862b9d7d11e37624fb1c00a16d61faf55115d970628b/propcache-0.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:c214999039d4f2a5b2073ac506bba279945233da8c786e490d411dfc30f855c1", size = 44117 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0f/2a/329e0547cf2def8857157f9477669043e75524cc3e6251cef332b3ff256f/propcache-0.2.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aca405706e0b0a44cc6bfd41fbe89919a6a56999157f6de7e182a990c36e37bc", size = 77002 },
|
||||
{ url = "https://files.pythonhosted.org/packages/12/2d/c4df5415e2382f840dc2ecbca0eeb2293024bc28e57a80392f2012b4708c/propcache-0.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:12d1083f001ace206fe34b6bdc2cb94be66d57a850866f0b908972f90996b3e9", size = 44639 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d0/5a/21aaa4ea2f326edaa4e240959ac8b8386ea31dedfdaa636a3544d9e7a408/propcache-0.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:d93f3307ad32a27bda2e88ec81134b823c240aa3abb55821a8da553eed8d9439", size = 44049 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/3e/021b6cd86c0acc90d74784ccbb66808b0bd36067a1bf3e2deb0f3845f618/propcache-0.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ba278acf14471d36316159c94a802933d10b6a1e117b8554fe0d0d9b75c9d536", size = 224819 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/57/c2fdeed1b3b8918b1770a133ba5c43ad3d78e18285b0c06364861ef5cc38/propcache-0.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4e6281aedfca15301c41f74d7005e6e3f4ca143584ba696ac69df4f02f40d629", size = 229625 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/81/70d4ff57bf2877b5780b466471bebf5892f851a7e2ca0ae7ffd728220281/propcache-0.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5b750a8e5a1262434fb1517ddf64b5de58327f1adc3524a5e44c2ca43305eb0b", size = 232934 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3c/b9/bb51ea95d73b3fb4100cb95adbd4e1acaf2cbb1fd1083f5468eeb4a099a8/propcache-0.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf72af5e0fb40e9babf594308911436c8efde3cb5e75b6f206c34ad18be5c052", size = 227361 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/20/3c6d696cd6fd70b29445960cc803b1851a1131e7a2e4ee261ee48e002bcd/propcache-0.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b2d0a12018b04f4cb820781ec0dffb5f7c7c1d2a5cd22bff7fb055a2cb19ebce", size = 213904 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a1/cb/1593bfc5ac6d40c010fa823f128056d6bc25b667f5393781e37d62f12005/propcache-0.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:e800776a79a5aabdb17dcc2346a7d66d0777e942e4cd251defeb084762ecd17d", size = 212632 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/5c/e95617e222be14a34c709442a0ec179f3207f8a2b900273720501a70ec5e/propcache-0.2.1-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:4160d9283bd382fa6c0c2b5e017acc95bc183570cd70968b9202ad6d8fc48dce", size = 207897 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/3b/56c5ab3dc00f6375fbcdeefdede5adf9bee94f1fab04adc8db118f0f9e25/propcache-0.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:30b43e74f1359353341a7adb783c8f1b1c676367b011709f466f42fda2045e95", size = 208118 },
|
||||
{ url = "https://files.pythonhosted.org/packages/86/25/d7ef738323fbc6ebcbce33eb2a19c5e07a89a3df2fded206065bd5e868a9/propcache-0.2.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:58791550b27d5488b1bb52bc96328456095d96206a250d28d874fafe11b3dfaf", size = 217851 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b3/77/763e6cef1852cf1ba740590364ec50309b89d1c818e3256d3929eb92fabf/propcache-0.2.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0f022d381747f0dfe27e99d928e31bc51a18b65bb9e481ae0af1380a6725dd1f", size = 222630 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4f/e9/0f86be33602089c701696fbed8d8c4c07b6ee9605c5b7536fd27ed540c5b/propcache-0.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:297878dc9d0a334358f9b608b56d02e72899f3b8499fc6044133f0d319e2ec30", size = 216269 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cc/02/5ac83217d522394b6a2e81a2e888167e7ca629ef6569a3f09852d6dcb01a/propcache-0.2.1-cp313-cp313-win32.whl", hash = "sha256:ddfab44e4489bd79bda09d84c430677fc7f0a4939a73d2bba3073036f487a0a6", size = 39472 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f4/33/d6f5420252a36034bc8a3a01171bc55b4bff5df50d1c63d9caa50693662f/propcache-0.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:556fc6c10989f19a179e4321e5d678db8eb2924131e64652a51fe83e4c3db0e1", size = 43363 },
|
||||
{ url = "https://files.pythonhosted.org/packages/41/b6/c5319caea262f4821995dca2107483b94a3345d4607ad797c76cb9c36bcc/propcache-0.2.1-py3-none-any.whl", hash = "sha256:52277518d6aae65536e9cea52d4e7fd2f7a66f4aa2d30ed3f2fcea620ace3c54", size = 11818 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -960,7 +963,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "pytest"
|
||||
version = "8.3.3"
|
||||
version = "8.3.4"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "colorama", marker = "sys_platform == 'win32'" },
|
||||
@ -968,21 +971,21 @@ dependencies = [
|
||||
{ name = "packaging" },
|
||||
{ name = "pluggy" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/8b/6c/62bbd536103af674e227c41a8f3dcd022d591f6eed5facb5a0f31ee33bbc/pytest-8.3.3.tar.gz", hash = "sha256:70b98107bd648308a7952b06e6ca9a50bc660be218d53c257cc1fc94fda10181", size = 1442487 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/05/35/30e0d83068951d90a01852cb1cef56e5d8a09d20c7f511634cc2f7e0372a/pytest-8.3.4.tar.gz", hash = "sha256:965370d062bce11e73868e0335abac31b4d3de0e82f4007408d242b4f8610761", size = 1445919 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/77/7440a06a8ead44c7757a64362dd22df5760f9b12dc5f11b6188cd2fc27a0/pytest-8.3.3-py3-none-any.whl", hash = "sha256:a6853c7375b2663155079443d2e45de913a911a11d669df02a50814944db57b2", size = 342341 },
|
||||
{ url = "https://files.pythonhosted.org/packages/11/92/76a1c94d3afee238333bc0a42b82935dd8f9cf8ce9e336ff87ee14d9e1cf/pytest-8.3.4-py3-none-any.whl", hash = "sha256:50e16d954148559c9a74109af1eaf0c945ba2d8f30f0a3d3335edde19788b6f6", size = 343083 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
name = "pytest-asyncio"
|
||||
version = "0.24.0"
|
||||
version = "0.25.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "pytest" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/52/6d/c6cf50ce320cf8611df7a1254d86233b3df7cc07f9b5f5cbcb82e08aa534/pytest_asyncio-0.24.0.tar.gz", hash = "sha256:d081d828e576d85f875399194281e92bf8a68d60d72d1a2faf2feddb6c46b276", size = 49855 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/94/18/82fcb4ee47d66d99f6cd1efc0b11b2a25029f303c599a5afda7c1bca4254/pytest_asyncio-0.25.0.tar.gz", hash = "sha256:8c0610303c9e0442a5db8604505fc0f545456ba1528824842b37b4a626cbf609", size = 53298 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/96/31/6607dab48616902f76885dfcf62c08d929796fc3b2d2318faf9fd54dbed9/pytest_asyncio-0.24.0-py3-none-any.whl", hash = "sha256:a811296ed596b69bf0b6f3dc40f83bcaf341b155a269052d82efa2b25ac7037b", size = 18024 },
|
||||
{ url = "https://files.pythonhosted.org/packages/88/56/2ee0cab25c11d4e38738a2a98c645a8f002e2ecf7b5ed774c70d53b92bb1/pytest_asyncio-0.25.0-py3-none-any.whl", hash = "sha256:db5432d18eac6b7e28b46dcd9b69921b55c3b1086e85febfe04e70b18d9e81b3", size = 19245 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1000,15 +1003,15 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "pytest-freezer"
|
||||
version = "0.4.8"
|
||||
version = "0.4.9"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "freezegun" },
|
||||
{ name = "pytest" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/69/fa/a93d40dd50f712c276a5a15f9c075bee932cc4d28c376e60b4a35904976d/pytest_freezer-0.4.8.tar.gz", hash = "sha256:8ee2f724b3ff3540523fa355958a22e6f4c1c819928b78a7a183ae4248ce6ee6", size = 3212 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/81/f0/98dcbc5324064360b19850b14c84cea9ca50785d921741dbfc442346e925/pytest_freezer-0.4.9.tar.gz", hash = "sha256:21bf16bc9cc46bf98f94382c4b5c3c389be7056ff0be33029111ae11b3f1c82a", size = 3177 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d8/4e/ba488639516a341810aeaeb4b32b70abb0923e53f7c4d14d673dc114d35a/pytest_freezer-0.4.8-py3-none-any.whl", hash = "sha256:644ce7ddb8ba52b92a1df0a80a699bad2b93514c55cf92e9f2517b68ebe74814", size = 3228 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c1/e9/30252bc05bcf67200a17f4f0b4cc7598f0a68df4fa9fa356193aa899f145/pytest_freezer-0.4.9-py3-none-any.whl", hash = "sha256:8b6c50523b7d4aec4590b52bfa5ff766d772ce506e2bf4846c88041ea9ccae59", size = 3192 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1088,7 +1091,7 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "python-kasa"
|
||||
version = "0.8.1"
|
||||
version = "0.9.0"
|
||||
source = { editable = "." }
|
||||
dependencies = [
|
||||
{ name = "aiohttp" },
|
||||
@ -1265,11 +1268,11 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "six"
|
||||
version = "1.16.0"
|
||||
version = "1.17.0"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/71/39/171f1c67cd00715f190ba0b100d606d440a28c93c7714febeca8b79af85e/six-1.16.0.tar.gz", hash = "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", size = 34041 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/94/e7/b2c673351809dca68a0e064b6af791aa332cf192da575fd474ed7d6f16a2/six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81", size = 34031 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/5a/e7c31adbe875f2abbb91bd84cf2dc52d792b5a01506781dbcf25c91daf11/six-1.16.0-py2.py3-none-any.whl", hash = "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254", size = 11053 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b7/ce/149a00dd41f10bc29e5921b496af8b574d8413afcd5e30dfa0ed46c2cc5e/six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274", size = 11050 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1381,14 +1384,14 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "sphinxcontrib-programoutput"
|
||||
version = "0.17"
|
||||
version = "0.18"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "sphinx" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/49/fe/8a6d8763674b3d3814a6008a83eb8002b6da188710dd7f4654ec77b4a8ac/sphinxcontrib-programoutput-0.17.tar.gz", hash = "sha256:300ee9b8caee8355d25cc74b4d1c7efd12e608d2ad165e3141d31e6fbc152b7f", size = 24067 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/3f/c0/834af2290f8477213ec0dd60e90104f5644aa0c37b1a0d6f0a2b5efe03c4/sphinxcontrib_programoutput-0.18.tar.gz", hash = "sha256:09e68b6411d937a80b6085f4fdeaa42e0dc5555480385938465f410589d2eed8", size = 26333 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/30/ee/b7be4b3f45f4e36bfa6c444cd234098e0d09880379c67a43e6bb9ab99a86/sphinxcontrib_programoutput-0.17-py2.py3-none-any.whl", hash = "sha256:0ef1c1d9159dbe7103077748214305eb4e0138e861feb71c0c346afc5fe97f84", size = 22131 },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/2c/7aec6e0580f666d4f61474a50c4995a98abfff27d827f0e7bc8c4fa528f5/sphinxcontrib_programoutput-0.18-py3-none-any.whl", hash = "sha256:8a651bc85de69a808a064ff0e48d06c12b9347da4fe5fdb1e94914b01e1b0c36", size = 20346 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1429,11 +1432,41 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "tomli"
|
||||
version = "2.1.0"
|
||||
version = "2.2.1"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/1e/e4/1b6cbcc82d8832dd0ce34767d5c560df8a3547ad8cbc427f34601415930a/tomli-2.1.0.tar.gz", hash = "sha256:3f646cae2aec94e17d04973e4249548320197cfabdf130015d023de4b74d8ab8", size = 16622 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/18/87/302344fed471e44a87289cf4967697d07e532f2421fdaf868a303cbae4ff/tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff", size = 17175 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/de/f7/4da0ffe1892122c9ea096c57f64c2753ae5dd3ce85488802d11b0992cc6d/tomli-2.1.0-py3-none-any.whl", hash = "sha256:a5c57c3d1c56f5ccdf89f6523458f60ef716e210fc47c4cfb188c5ba473e0391", size = 13750 },
|
||||
{ url = "https://files.pythonhosted.org/packages/43/ca/75707e6efa2b37c77dadb324ae7d9571cb424e61ea73fad7c56c2d14527f/tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249", size = 131077 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/16/51ae563a8615d472fdbffc43a3f3d46588c264ac4f024f63f01283becfbb/tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6", size = 123429 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f1/dd/4f6cd1e7b160041db83c694abc78e100473c15d54620083dbd5aae7b990e/tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a", size = 226067 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a9/6b/c54ede5dc70d648cc6361eaf429304b02f2871a345bbdd51e993d6cdf550/tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee", size = 236030 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1f/47/999514fa49cfaf7a92c805a86c3c43f4215621855d151b61c602abb38091/tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e", size = 240898 },
|
||||
{ url = "https://files.pythonhosted.org/packages/73/41/0a01279a7ae09ee1573b423318e7934674ce06eb33f50936655071d81a24/tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4", size = 229894 },
|
||||
{ url = "https://files.pythonhosted.org/packages/55/18/5d8bc5b0a0362311ce4d18830a5d28943667599a60d20118074ea1b01bb7/tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106", size = 245319 },
|
||||
{ url = "https://files.pythonhosted.org/packages/92/a3/7ade0576d17f3cdf5ff44d61390d4b3febb8a9fc2b480c75c47ea048c646/tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8", size = 238273 },
|
||||
{ url = "https://files.pythonhosted.org/packages/72/6f/fa64ef058ac1446a1e51110c375339b3ec6be245af9d14c87c4a6412dd32/tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff", size = 98310 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6a/1c/4a2dcde4a51b81be3530565e92eda625d94dafb46dbeb15069df4caffc34/tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b", size = 108309 },
|
||||
{ url = "https://files.pythonhosted.org/packages/52/e1/f8af4c2fcde17500422858155aeb0d7e93477a0d59a98e56cbfe75070fd0/tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea", size = 132762 },
|
||||
{ url = "https://files.pythonhosted.org/packages/03/b8/152c68bb84fc00396b83e7bbddd5ec0bd3dd409db4195e2a9b3e398ad2e3/tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8", size = 123453 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/d6/fc9267af9166f79ac528ff7e8c55c8181ded34eb4b0e93daa767b8841573/tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192", size = 233486 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5c/51/51c3f2884d7bab89af25f678447ea7d297b53b5a3b5730a7cb2ef6069f07/tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222", size = 242349 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/df/bfa89627d13a5cc22402e441e8a931ef2108403db390ff3345c05253935e/tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77", size = 252159 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9e/6e/fa2b916dced65763a5168c6ccb91066f7639bdc88b48adda990db10c8c0b/tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6", size = 237243 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/04/885d3b1f650e1153cbb93a6a9782c58a972b94ea4483ae4ac5cedd5e4a09/tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd", size = 259645 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9c/de/6b432d66e986e501586da298e28ebeefd3edc2c780f3ad73d22566034239/tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e", size = 244584 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1c/9a/47c0449b98e6e7d1be6cbac02f93dd79003234ddc4aaab6ba07a9a7482e2/tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98", size = 98875 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ef/60/9b9638f081c6f1261e2688bd487625cd1e660d0a85bd469e91d8db969734/tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4", size = 109418 },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/90/2ee5f2e0362cb8a0b6499dc44f4d7d48f8fff06d28ba46e6f1eaa61a1388/tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7", size = 132708 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c0/ec/46b4108816de6b385141f082ba99e315501ccd0a2ea23db4a100dd3990ea/tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c", size = 123582 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a0/bd/b470466d0137b37b68d24556c38a0cc819e8febe392d5b199dcd7f578365/tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13", size = 232543 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/e5/82e80ff3b751373f7cead2815bcbe2d51c895b3c990686741a8e56ec42ab/tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281", size = 241691 },
|
||||
{ url = "https://files.pythonhosted.org/packages/05/7e/2a110bc2713557d6a1bfb06af23dd01e7dde52b6ee7dadc589868f9abfac/tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272", size = 251170 },
|
||||
{ url = "https://files.pythonhosted.org/packages/64/7b/22d713946efe00e0adbcdfd6d1aa119ae03fd0b60ebed51ebb3fa9f5a2e5/tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140", size = 236530 },
|
||||
{ url = "https://files.pythonhosted.org/packages/38/31/3a76f67da4b0cf37b742ca76beaf819dca0ebef26d78fc794a576e08accf/tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2", size = 258666 },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/10/5af1293da642aded87e8a988753945d0cf7e00a9452d3911dd3bb354c9e2/tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744", size = 243954 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5b/b9/1ed31d167be802da0fc95020d04cd27b7d7065cc6fbefdd2f9186f60d7bd/tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec", size = 98724 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c7/32/b0963458706accd9afcfeb867c0f9175a741bf7b19cd424230714d722198/tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69", size = 109383 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6e/c2/61d3e0f47e2b74ef40a68b9e6ad5984f6241a942f7cd3bbfbdbd03861ea9/tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc", size = 14257 },
|
||||
]
|
||||
|
||||
[[package]]
|
||||
@ -1506,62 +1539,62 @@ wheels = [
|
||||
|
||||
[[package]]
|
||||
name = "yarl"
|
||||
version = "1.18.0"
|
||||
version = "1.18.3"
|
||||
source = { registry = "https://pypi.org/simple" }
|
||||
dependencies = [
|
||||
{ name = "idna" },
|
||||
{ name = "multidict" },
|
||||
{ name = "propcache" },
|
||||
]
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/5e/4b/53db4ecad4d54535aff3dfda1f00d6363d79455f62b11b8ca97b82746bd2/yarl-1.18.0.tar.gz", hash = "sha256:20d95535e7d833889982bfe7cc321b7f63bf8879788fee982c76ae2b24cfb715", size = 180098 }
|
||||
sdist = { url = "https://files.pythonhosted.org/packages/b7/9d/4b94a8e6d2b51b599516a5cb88e5bc99b4d8d4583e468057eaa29d5f0918/yarl-1.18.3.tar.gz", hash = "sha256:ac1801c45cbf77b6c99242eeff4fffb5e4e73a800b5c4ad4fc0be5def634d2e1", size = 181062 }
|
||||
wheels = [
|
||||
{ url = "https://files.pythonhosted.org/packages/06/45/6ad7135d1c4ad3a6a49e2c37dc78a1805a7871879c03c3495d64c9605d49/yarl-1.18.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b8e8c516dc4e1a51d86ac975b0350735007e554c962281c432eaa5822aa9765c", size = 141283 },
|
||||
{ url = "https://files.pythonhosted.org/packages/45/6d/24b70ae33107d6eba303ed0ebfdf1164fe2219656e7594ca58628ebc0f1d/yarl-1.18.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2e6b4466714a73f5251d84b471475850954f1fa6acce4d3f404da1d55d644c34", size = 94082 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8a/0e/da720989be11b662ca847ace58f468b52310a9b03e52ac62c144755f9d75/yarl-1.18.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:c893f8c1a6d48b25961e00922724732d00b39de8bb0b451307482dc87bddcd74", size = 92017 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/76/e5c91681fa54658943cb88673fb19b3355c3a8ae911a33a2621b6320990d/yarl-1.18.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13aaf2bdbc8c86ddce48626b15f4987f22e80d898818d735b20bd58f17292ee8", size = 340359 },
|
||||
{ url = "https://files.pythonhosted.org/packages/cf/77/02cf72f09dea20980dea4ebe40dfb2c24916b864aec869a19f715428e0f0/yarl-1.18.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:dd21c0128e301851de51bc607b0a6da50e82dc34e9601f4b508d08cc89ee7929", size = 356336 },
|
||||
{ url = "https://files.pythonhosted.org/packages/17/66/83a88d04e4fc243dd26109f3e3d6412f67819ab1142dadbce49706ef4df4/yarl-1.18.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:205de377bd23365cd85562c9c6c33844050a93661640fda38e0567d2826b50df", size = 353730 },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/77/0b205a532d22756ab250ab21924d362f910a23d641c82faec1c4ad7f6077/yarl-1.18.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ed69af4fe2a0949b1ea1d012bf065c77b4c7822bad4737f17807af2adb15a73c", size = 343882 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/47/2081ddce3da6096889c3947bdc21907d0fa15939909b10219254fe116841/yarl-1.18.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8e1c18890091aa3cc8a77967943476b729dc2016f4cfe11e45d89b12519d4a93", size = 335873 },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/3c/437304394494e757ae927c9a81bacc4bcdf7351a1d4e811d95b02cb6dbae/yarl-1.18.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:91b8fb9427e33f83ca2ba9501221ffaac1ecf0407f758c4d2f283c523da185ee", size = 347725 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/fb/fa6c642bc052fbe6370ed5da765579650510157dea354fe9e8177c3bc34a/yarl-1.18.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:536a7a8a53b75b2e98ff96edb2dfb91a26b81c4fed82782035767db5a465be46", size = 346161 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b0/09/8c0cf68a0fcfe3b060c9e5857bb35735bc72a4cf4075043632c636d007e9/yarl-1.18.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:a64619a9c47c25582190af38e9eb382279ad42e1f06034f14d794670796016c0", size = 349924 },
|
||||
{ url = "https://files.pythonhosted.org/packages/bf/4b/1efe10fd51e2cedf53195d688fa270efbcd64a015c61d029d49c20bf0af7/yarl-1.18.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c73a6bbc97ba1b5a0c3c992ae93d721c395bdbb120492759b94cc1ac71bc6350", size = 361865 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/1b/2b5efd6df06bf938f7e154dee8e2ab22d148f3311a92bf4da642aaaf2fc5/yarl-1.18.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:a173401d7821a2a81c7b47d4e7d5c4021375a1441af0c58611c1957445055056", size = 366030 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f8/db/786a5684f79278e62271038a698f56a51960f9e643be5d3eff82712f0b1c/yarl-1.18.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:7520e799b1f84e095cce919bd6c23c9d49472deeef25fe1ef960b04cca51c3fc", size = 358902 },
|
||||
{ url = "https://files.pythonhosted.org/packages/91/2f/437d0de062f1a3e3cb17573971b3832232443241133580c2ba3da5001d06/yarl-1.18.0-cp311-cp311-win32.whl", hash = "sha256:c4cb992d8090d5ae5f7afa6754d7211c578be0c45f54d3d94f7781c495d56716", size = 84138 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9d/85/035719a9266bce85ecde820aa3f8c46f3b18c3d7ba9ff51367b2fa4ae2a2/yarl-1.18.0-cp311-cp311-win_amd64.whl", hash = "sha256:52c136f348605974c9b1c878addd6b7a60e3bf2245833e370862009b86fa4689", size = 90765 },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/36/c579b80a5c76c0d41c8e08baddb3e6940dfc20569db579a5691392c52afa/yarl-1.18.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1ece25e2251c28bab737bdf0519c88189b3dd9492dc086a1d77336d940c28ced", size = 142376 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0c/5f/e247dc7c0607a0c505fea6c839721844bee55686dfb183c7d7b8ef8a9cb1/yarl-1.18.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:454902dc1830d935c90b5b53c863ba2a98dcde0fbaa31ca2ed1ad33b2a7171c6", size = 94692 },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/e1/3081b578a6f21961711b9a1c49c2947abb3b0d0dd9537378fb06777ce8ee/yarl-1.18.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:01be8688fc211dc237e628fcc209dda412d35de7642453059a0553747018d075", size = 92527 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2f/fa/d9e1b9fbafa4cc82cd3980b5314741b33c2fe16308d725449a23aed32021/yarl-1.18.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4d26f1fa9fa2167bb238f6f4b20218eb4e88dd3ef21bb8f97439fa6b5313e30d", size = 332096 },
|
||||
{ url = "https://files.pythonhosted.org/packages/93/b6/dd27165114317875838e216214fb86338dc63d2e50855a8f2a12de2a7fe5/yarl-1.18.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b234a4a9248a9f000b7a5dfe84b8cb6210ee5120ae70eb72a4dcbdb4c528f72f", size = 342047 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fc/9f/bad434b5279ae7a356844e14dc771c3d29eb928140bbc01621af811c8a27/yarl-1.18.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:fe94d1de77c4cd8caff1bd5480e22342dbd54c93929f5943495d9c1e8abe9f42", size = 341712 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/9f/63864f43d131ba8c8cdf1bde5dd3f02f0eff8a7c883a5d7fad32f204fda5/yarl-1.18.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b4c90c5363c6b0a54188122b61edb919c2cd1119684999d08cd5e538813a28e", size = 336654 },
|
||||
{ url = "https://files.pythonhosted.org/packages/20/30/b4542bbd9be73de155213207eec019f6fe6495885f7dd59aa1ff705a041b/yarl-1.18.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:49a98ecadc5a241c9ba06de08127ee4796e1009555efd791bac514207862b43d", size = 325484 },
|
||||
{ url = "https://files.pythonhosted.org/packages/69/bc/e2a9808ec26989cf0d1b98fe7b3cc45c1c6506b5ea4fe43ece5991f28f34/yarl-1.18.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:9106025c7f261f9f5144f9aa7681d43867eed06349a7cfb297a1bc804de2f0d1", size = 344213 },
|
||||
{ url = "https://files.pythonhosted.org/packages/e2/17/0ee5a68886aca1a8071b0d24a1e1c0fd9970dead2ef2d5e26e027fb7ce88/yarl-1.18.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:f275ede6199d0f1ed4ea5d55a7b7573ccd40d97aee7808559e1298fe6efc8dbd", size = 340517 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/db/1fe4ef38ee852bff5ec8f5367d718b3a7dac7520f344b8e50306f68a2940/yarl-1.18.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:f7edeb1dcc7f50a2c8e08b9dc13a413903b7817e72273f00878cb70e766bdb3b", size = 346234 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b4/ee/5e5bccdb821eb9949ba66abb4d19e3299eee00282e37b42f65236120e892/yarl-1.18.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c083f6dd6951b86e484ebfc9c3524b49bcaa9c420cb4b2a78ef9f7a512bfcc85", size = 359625 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3f/43/95a64d9e7ab4aa1c34fc5ea0edb35b581bc6ad33fd960a8ae34c2040b319/yarl-1.18.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:80741ec5b471fbdfb997821b2842c59660a1c930ceb42f8a84ba8ca0f25a66aa", size = 364239 },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/19/09ce976c624c9d3cc898f0be5035ddef0c0759d85b2313321cfe77b69915/yarl-1.18.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b1a3297b9cad594e1ff0c040d2881d7d3a74124a3c73e00c3c71526a1234a9f7", size = 357599 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/35/6f33fd29791af2ec161aebe8abe63e788c2b74a6c7e8f29c92e5f5e96849/yarl-1.18.0-cp312-cp312-win32.whl", hash = "sha256:cd6ab7d6776c186f544f893b45ee0c883542b35e8a493db74665d2e594d3ca75", size = 83832 },
|
||||
{ url = "https://files.pythonhosted.org/packages/4e/8e/cdb40ef98597be107de67b11e2f1f23f911e0f1416b938885d17a338e304/yarl-1.18.0-cp312-cp312-win_amd64.whl", hash = "sha256:039c299a0864d1f43c3e31570045635034ea7021db41bf4842693a72aca8df3a", size = 90132 },
|
||||
{ url = "https://files.pythonhosted.org/packages/2b/77/2196b657c66f97adaef0244e9e015f30eac0df59c31ad540f79ce328feed/yarl-1.18.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:6fb64dd45453225f57d82c4764818d7a205ee31ce193e9f0086e493916bd4f72", size = 140512 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/d8/2bb6e26fddba5c01bad284e4571178c651b97e8e06318efcaa16e07eb9fd/yarl-1.18.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:3adaaf9c6b1b4fc258584f4443f24d775a2086aee82d1387e48a8b4f3d6aecf6", size = 93875 },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/e4/99fbb884dd9f814fb0037dc1783766bb9edcd57b32a76f3ec5ac5c5772d7/yarl-1.18.0-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:da206d1ec78438a563c5429ab808a2b23ad7bc025c8adbf08540dde202be37d5", size = 91705 },
|
||||
{ url = "https://files.pythonhosted.org/packages/3b/a2/5bd86eca9449e6b15d3b08005cf4e58e3da972240c2bee427b358c311549/yarl-1.18.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:576d258b21c1db4c6449b1c572c75d03f16a482eb380be8003682bdbe7db2f28", size = 333325 },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/50/a218da5f159cd985685bc72c500bb1a7fd2d60035d2339b8a9d9e1f99194/yarl-1.18.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c60e547c0a375c4bfcdd60eef82e7e0e8698bf84c239d715f5c1278a73050393", size = 344121 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a4/e3/830ae465811198b4b5ebecd674b5b3dca4d222af2155eb2144bfe190bbb8/yarl-1.18.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:e3818eabaefb90adeb5e0f62f047310079d426387991106d4fbf3519eec7d90a", size = 345163 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7a/74/05c4326877ca541eee77b1ef74b7ac8081343d3957af8f9291ca6eca6fec/yarl-1.18.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5f72421246c21af6a92fbc8c13b6d4c5427dfd949049b937c3b731f2f9076bd", size = 339130 },
|
||||
{ url = "https://files.pythonhosted.org/packages/29/42/842f35aa1dae25d132119ee92185e8c75d8b9b7c83346506bd31e9fa217f/yarl-1.18.0-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:7fa7d37f2ada0f42e0723632993ed422f2a679af0e200874d9d861720a54f53e", size = 326418 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f9/ed/65c0514f2d1e8b92a61f564c914381d078766cab38b5fbde355b3b3af1fb/yarl-1.18.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:42ba84e2ac26a3f252715f8ec17e6fdc0cbf95b9617c5367579fafcd7fba50eb", size = 345204 },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/31/351f64f0530c372fa01160f38330f44478e7bf3092f5ce2bfcb91605561d/yarl-1.18.0-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:6a49ad0102c0f0ba839628d0bf45973c86ce7b590cdedf7540d5b1833ddc6f00", size = 341652 },
|
||||
{ url = "https://files.pythonhosted.org/packages/49/aa/0c6e666c218d567727c1d040d01575685e7f9b18052fd68a59c9f61fe5d9/yarl-1.18.0-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:96404e8d5e1bbe36bdaa84ef89dc36f0e75939e060ca5cd45451aba01db02902", size = 347257 },
|
||||
{ url = "https://files.pythonhosted.org/packages/36/0b/33a093b0e13bb8cd0f27301779661ff325270b6644929001f8f33307357d/yarl-1.18.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:a0509475d714df8f6d498935b3f307cd122c4ca76f7d426c7e1bb791bcd87eda", size = 359735 },
|
||||
{ url = "https://files.pythonhosted.org/packages/a8/92/dcc0b37c48632e71ffc2b5f8b0509347a0bde55ab5862ff755dce9dd56c4/yarl-1.18.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:1ff116f0285b5c8b3b9a2680aeca29a858b3b9e0402fc79fd850b32c2bcb9f8b", size = 365982 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0e/39/30e2a24a7a6c628dccb13eb6c4a03db5f6cd1eb2c6cda56a61ddef764c11/yarl-1.18.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:e2580c1d7e66e6d29d6e11855e3b1c6381971e0edd9a5066e6c14d79bc8967af", size = 360128 },
|
||||
{ url = "https://files.pythonhosted.org/packages/76/13/12b65dca23b1fb8ae44269a4d24048fd32ac90b445c985b0a46fdfa30cfe/yarl-1.18.0-cp313-cp313-win32.whl", hash = "sha256:14408cc4d34e202caba7b5ac9cc84700e3421a9e2d1b157d744d101b061a4a88", size = 309888 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f6/60/478d3d41a4bf0b9e7dca74d870d114e775d1ff7156b7d1e0e9972e8f97fd/yarl-1.18.0-cp313-cp313-win_amd64.whl", hash = "sha256:1db1537e9cb846eb0ff206eac667f627794be8b71368c1ab3207ec7b6f8c5afc", size = 315459 },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/9c/3f7ab894a37b1520291247cbc9ea6756228d098dae5b37eec848d404a204/yarl-1.18.0-py3-none-any.whl", hash = "sha256:dbf53db46f7cf176ee01d8d98c39381440776fcda13779d269a8ba664f69bec0", size = 44840 },
|
||||
{ url = "https://files.pythonhosted.org/packages/40/93/282b5f4898d8e8efaf0790ba6d10e2245d2c9f30e199d1a85cae9356098c/yarl-1.18.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8503ad47387b8ebd39cbbbdf0bf113e17330ffd339ba1144074da24c545f0069", size = 141555 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6d/9c/0a49af78df099c283ca3444560f10718fadb8a18dc8b3edf8c7bd9fd7d89/yarl-1.18.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:02ddb6756f8f4517a2d5e99d8b2f272488e18dd0bfbc802f31c16c6c20f22193", size = 94351 },
|
||||
{ url = "https://files.pythonhosted.org/packages/5a/a1/205ab51e148fdcedad189ca8dd587794c6f119882437d04c33c01a75dece/yarl-1.18.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:67a283dd2882ac98cc6318384f565bffc751ab564605959df4752d42483ad889", size = 92286 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ed/fe/88b690b30f3f59275fb674f5f93ddd4a3ae796c2b62e5bb9ece8a4914b83/yarl-1.18.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d980e0325b6eddc81331d3f4551e2a333999fb176fd153e075c6d1c2530aa8a8", size = 340649 },
|
||||
{ url = "https://files.pythonhosted.org/packages/07/eb/3b65499b568e01f36e847cebdc8d7ccb51fff716dbda1ae83c3cbb8ca1c9/yarl-1.18.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b643562c12680b01e17239be267bc306bbc6aac1f34f6444d1bded0c5ce438ca", size = 356623 },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/46/f559dc184280b745fc76ec6b1954de2c55595f0ec0a7614238b9ebf69618/yarl-1.18.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c017a3b6df3a1bd45b9fa49a0f54005e53fbcad16633870104b66fa1a30a29d8", size = 354007 },
|
||||
{ url = "https://files.pythonhosted.org/packages/af/ba/1865d85212351ad160f19fb99808acf23aab9a0f8ff31c8c9f1b4d671fc9/yarl-1.18.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:75674776d96d7b851b6498f17824ba17849d790a44d282929c42dbb77d4f17ae", size = 344145 },
|
||||
{ url = "https://files.pythonhosted.org/packages/94/cb/5c3e975d77755d7b3d5193e92056b19d83752ea2da7ab394e22260a7b824/yarl-1.18.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ccaa3a4b521b780a7e771cc336a2dba389a0861592bbce09a476190bb0c8b4b3", size = 336133 },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/89/b77d3fd249ab52a5c40859815765d35c91425b6bb82e7427ab2f78f5ff55/yarl-1.18.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:2d06d3005e668744e11ed80812e61efd77d70bb7f03e33c1598c301eea20efbb", size = 347967 },
|
||||
{ url = "https://files.pythonhosted.org/packages/35/bd/f6b7630ba2cc06c319c3235634c582a6ab014d52311e7d7c22f9518189b5/yarl-1.18.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9d41beda9dc97ca9ab0b9888cb71f7539124bc05df02c0cff6e5acc5a19dcc6e", size = 346397 },
|
||||
{ url = "https://files.pythonhosted.org/packages/18/1a/0b4e367d5a72d1f095318344848e93ea70da728118221f84f1bf6c1e39e7/yarl-1.18.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ba23302c0c61a9999784e73809427c9dbedd79f66a13d84ad1b1943802eaaf59", size = 350206 },
|
||||
{ url = "https://files.pythonhosted.org/packages/b5/cf/320fff4367341fb77809a2d8d7fe75b5d323a8e1b35710aafe41fdbf327b/yarl-1.18.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:6748dbf9bfa5ba1afcc7556b71cda0d7ce5f24768043a02a58846e4a443d808d", size = 362089 },
|
||||
{ url = "https://files.pythonhosted.org/packages/57/cf/aadba261d8b920253204085268bad5e8cdd86b50162fcb1b10c10834885a/yarl-1.18.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:0b0cad37311123211dc91eadcb322ef4d4a66008d3e1bdc404808992260e1a0e", size = 366267 },
|
||||
{ url = "https://files.pythonhosted.org/packages/54/58/fb4cadd81acdee6dafe14abeb258f876e4dd410518099ae9a35c88d8097c/yarl-1.18.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0fb2171a4486bb075316ee754c6d8382ea6eb8b399d4ec62fde2b591f879778a", size = 359141 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/7a/4c571597589da4cd5c14ed2a0b17ac56ec9ee7ee615013f74653169e702d/yarl-1.18.3-cp311-cp311-win32.whl", hash = "sha256:61b1a825a13bef4a5f10b1885245377d3cd0bf87cba068e1d9a88c2ae36880e1", size = 84402 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ae/7b/8600250b3d89b625f1121d897062f629883c2f45339623b69b1747ec65fa/yarl-1.18.3-cp311-cp311-win_amd64.whl", hash = "sha256:b9d60031cf568c627d028239693fd718025719c02c9f55df0a53e587aab951b5", size = 91030 },
|
||||
{ url = "https://files.pythonhosted.org/packages/33/85/bd2e2729752ff4c77338e0102914897512e92496375e079ce0150a6dc306/yarl-1.18.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1dd4bdd05407ced96fed3d7f25dbbf88d2ffb045a0db60dbc247f5b3c5c25d50", size = 142644 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ff/74/1178322cc0f10288d7eefa6e4a85d8d2e28187ccab13d5b844e8b5d7c88d/yarl-1.18.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:7c33dd1931a95e5d9a772d0ac5e44cac8957eaf58e3c8da8c1414de7dd27c576", size = 94962 },
|
||||
{ url = "https://files.pythonhosted.org/packages/be/75/79c6acc0261e2c2ae8a1c41cf12265e91628c8c58ae91f5ff59e29c0787f/yarl-1.18.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:25b411eddcfd56a2f0cd6a384e9f4f7aa3efee14b188de13048c25b5e91f1640", size = 92795 },
|
||||
{ url = "https://files.pythonhosted.org/packages/6b/32/927b2d67a412c31199e83fefdce6e645247b4fb164aa1ecb35a0f9eb2058/yarl-1.18.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:436c4fc0a4d66b2badc6c5fc5ef4e47bb10e4fd9bf0c79524ac719a01f3607c2", size = 332368 },
|
||||
{ url = "https://files.pythonhosted.org/packages/19/e5/859fca07169d6eceeaa4fde1997c91d8abde4e9a7c018e371640c2da2b71/yarl-1.18.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e35ef8683211db69ffe129a25d5634319a677570ab6b2eba4afa860f54eeaf75", size = 342314 },
|
||||
{ url = "https://files.pythonhosted.org/packages/08/75/76b63ccd91c9e03ab213ef27ae6add2e3400e77e5cdddf8ed2dbc36e3f21/yarl-1.18.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:84b2deecba4a3f1a398df819151eb72d29bfeb3b69abb145a00ddc8d30094512", size = 341987 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1a/e1/a097d5755d3ea8479a42856f51d97eeff7a3a7160593332d98f2709b3580/yarl-1.18.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00e5a1fea0fd4f5bfa7440a47eff01d9822a65b4488f7cff83155a0f31a2ecba", size = 336914 },
|
||||
{ url = "https://files.pythonhosted.org/packages/0b/42/e1b4d0e396b7987feceebe565286c27bc085bf07d61a59508cdaf2d45e63/yarl-1.18.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d0e883008013c0e4aef84dcfe2a0b172c4d23c2669412cf5b3371003941f72bb", size = 325765 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7e/18/03a5834ccc9177f97ca1bbb245b93c13e58e8225276f01eedc4cc98ab820/yarl-1.18.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:5a3f356548e34a70b0172d8890006c37be92995f62d95a07b4a42e90fba54272", size = 344444 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c8/03/a713633bdde0640b0472aa197b5b86e90fbc4c5bc05b727b714cd8a40e6d/yarl-1.18.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ccd17349166b1bee6e529b4add61727d3f55edb7babbe4069b5764c9587a8cc6", size = 340760 },
|
||||
{ url = "https://files.pythonhosted.org/packages/eb/99/f6567e3f3bbad8fd101886ea0276c68ecb86a2b58be0f64077396cd4b95e/yarl-1.18.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b958ddd075ddba5b09bb0be8a6d9906d2ce933aee81100db289badbeb966f54e", size = 346484 },
|
||||
{ url = "https://files.pythonhosted.org/packages/8e/a9/84717c896b2fc6cb15bd4eecd64e34a2f0a9fd6669e69170c73a8b46795a/yarl-1.18.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c7d79f7d9aabd6011004e33b22bc13056a3e3fb54794d138af57f5ee9d9032cb", size = 359864 },
|
||||
{ url = "https://files.pythonhosted.org/packages/1e/2e/d0f5f1bef7ee93ed17e739ec8dbcb47794af891f7d165fa6014517b48169/yarl-1.18.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4891ed92157e5430874dad17b15eb1fda57627710756c27422200c52d8a4e393", size = 364537 },
|
||||
{ url = "https://files.pythonhosted.org/packages/97/8a/568d07c5d4964da5b02621a517532adb8ec5ba181ad1687191fffeda0ab6/yarl-1.18.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ce1af883b94304f493698b00d0f006d56aea98aeb49d75ec7d98cd4a777e9285", size = 357861 },
|
||||
{ url = "https://files.pythonhosted.org/packages/7d/e3/924c3f64b6b3077889df9a1ece1ed8947e7b61b0a933f2ec93041990a677/yarl-1.18.3-cp312-cp312-win32.whl", hash = "sha256:f91c4803173928a25e1a55b943c81f55b8872f0018be83e3ad4938adffb77dd2", size = 84097 },
|
||||
{ url = "https://files.pythonhosted.org/packages/34/45/0e055320daaabfc169b21ff6174567b2c910c45617b0d79c68d7ab349b02/yarl-1.18.3-cp312-cp312-win_amd64.whl", hash = "sha256:7e2ee16578af3b52ac2f334c3b1f92262f47e02cc6193c598502bd46f5cd1477", size = 90399 },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/c7/c790513d5328a8390be8f47be5d52e141f78b66c6c48f48d241ca6bd5265/yarl-1.18.3-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:90adb47ad432332d4f0bc28f83a5963f426ce9a1a8809f5e584e704b82685dcb", size = 140789 },
|
||||
{ url = "https://files.pythonhosted.org/packages/30/aa/a2f84e93554a578463e2edaaf2300faa61c8701f0898725842c704ba5444/yarl-1.18.3-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:913829534200eb0f789d45349e55203a091f45c37a2674678744ae52fae23efa", size = 94144 },
|
||||
{ url = "https://files.pythonhosted.org/packages/c6/fc/d68d8f83714b221a85ce7866832cba36d7c04a68fa6a960b908c2c84f325/yarl-1.18.3-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:ef9f7768395923c3039055c14334ba4d926f3baf7b776c923c93d80195624782", size = 91974 },
|
||||
{ url = "https://files.pythonhosted.org/packages/56/4e/d2563d8323a7e9a414b5b25341b3942af5902a2263d36d20fb17c40411e2/yarl-1.18.3-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:88a19f62ff30117e706ebc9090b8ecc79aeb77d0b1f5ec10d2d27a12bc9f66d0", size = 333587 },
|
||||
{ url = "https://files.pythonhosted.org/packages/25/c9/cfec0bc0cac8d054be223e9f2c7909d3e8442a856af9dbce7e3442a8ec8d/yarl-1.18.3-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e17c9361d46a4d5addf777c6dd5eab0715a7684c2f11b88c67ac37edfba6c482", size = 344386 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ab/5d/4c532190113b25f1364d25f4c319322e86232d69175b91f27e3ebc2caf9a/yarl-1.18.3-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1a74a13a4c857a84a845505fd2d68e54826a2cd01935a96efb1e9d86c728e186", size = 345421 },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/d1/6cdd1632da013aa6ba18cee4d750d953104a5e7aac44e249d9410a972bf5/yarl-1.18.3-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41f7ce59d6ee7741af71d82020346af364949314ed3d87553763a2df1829cc58", size = 339384 },
|
||||
{ url = "https://files.pythonhosted.org/packages/9a/c4/6b3c39bec352e441bd30f432cda6ba51681ab19bb8abe023f0d19777aad1/yarl-1.18.3-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f52a265001d830bc425f82ca9eabda94a64a4d753b07d623a9f2863fde532b53", size = 326689 },
|
||||
{ url = "https://files.pythonhosted.org/packages/23/30/07fb088f2eefdc0aa4fc1af4e3ca4eb1a3aadd1ce7d866d74c0f124e6a85/yarl-1.18.3-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:82123d0c954dc58db301f5021a01854a85bf1f3bb7d12ae0c01afc414a882ca2", size = 345453 },
|
||||
{ url = "https://files.pythonhosted.org/packages/63/09/d54befb48f9cd8eec43797f624ec37783a0266855f4930a91e3d5c7717f8/yarl-1.18.3-cp313-cp313-musllinux_1_2_armv7l.whl", hash = "sha256:2ec9bbba33b2d00999af4631a3397d1fd78290c48e2a3e52d8dd72db3a067ac8", size = 341872 },
|
||||
{ url = "https://files.pythonhosted.org/packages/91/26/fd0ef9bf29dd906a84b59f0cd1281e65b0c3e08c6aa94b57f7d11f593518/yarl-1.18.3-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:fbd6748e8ab9b41171bb95c6142faf068f5ef1511935a0aa07025438dd9a9bc1", size = 347497 },
|
||||
{ url = "https://files.pythonhosted.org/packages/d9/b5/14ac7a256d0511b2ac168d50d4b7d744aea1c1aa20c79f620d1059aab8b2/yarl-1.18.3-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:877d209b6aebeb5b16c42cbb377f5f94d9e556626b1bfff66d7b0d115be88d0a", size = 359981 },
|
||||
{ url = "https://files.pythonhosted.org/packages/ca/b3/d493221ad5cbd18bc07e642894030437e405e1413c4236dd5db6e46bcec9/yarl-1.18.3-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:b464c4ab4bfcb41e3bfd3f1c26600d038376c2de3297760dfe064d2cb7ea8e10", size = 366229 },
|
||||
{ url = "https://files.pythonhosted.org/packages/04/56/6a3e2a5d9152c56c346df9b8fb8edd2c8888b1e03f96324d457e5cf06d34/yarl-1.18.3-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:8d39d351e7faf01483cc7ff7c0213c412e38e5a340238826be7e0e4da450fdc8", size = 360383 },
|
||||
{ url = "https://files.pythonhosted.org/packages/fd/b7/4b3c7c7913a278d445cc6284e59b2e62fa25e72758f888b7a7a39eb8423f/yarl-1.18.3-cp313-cp313-win32.whl", hash = "sha256:61ee62ead9b68b9123ec24bc866cbef297dd266175d53296e2db5e7f797f902d", size = 310152 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/d5/688db678e987c3e0fb17867970700b92603cadf36c56e5fb08f23e822a0c/yarl-1.18.3-cp313-cp313-win_amd64.whl", hash = "sha256:578e281c393af575879990861823ef19d66e2b1d0098414855dd367e234f5b3c", size = 315723 },
|
||||
{ url = "https://files.pythonhosted.org/packages/f5/4b/a06e0ec3d155924f77835ed2d167ebd3b211a7b0853da1cf8d8414d784ef/yarl-1.18.3-py3-none-any.whl", hash = "sha256:b57f4f58099328dfb26c6a771d09fb20dbbae81d20cfb66141251ea063bd101b", size = 45109 },
|
||||
]
|
||||
|
Loading…
Reference in New Issue
Block a user