pyezvizapi 1.0.1.3__py3-none-any.whl → 1.0.1.5__py3-none-any.whl
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Potentially problematic release.
This version of pyezvizapi might be problematic. Click here for more details.
- pyezvizapi/__init__.py +2 -0
- pyezvizapi/api_endpoints.py +3 -1
- pyezvizapi/client.py +158 -21
- pyezvizapi/exceptions.py +4 -0
- {pyezvizapi-1.0.1.3.dist-info → pyezvizapi-1.0.1.5.dist-info}/METADATA +1 -1
- {pyezvizapi-1.0.1.3.dist-info → pyezvizapi-1.0.1.5.dist-info}/RECORD +11 -11
- {pyezvizapi-1.0.1.3.dist-info → pyezvizapi-1.0.1.5.dist-info}/WHEEL +0 -0
- {pyezvizapi-1.0.1.3.dist-info → pyezvizapi-1.0.1.5.dist-info}/entry_points.txt +0 -0
- {pyezvizapi-1.0.1.3.dist-info → pyezvizapi-1.0.1.5.dist-info}/licenses/LICENSE +0 -0
- {pyezvizapi-1.0.1.3.dist-info → pyezvizapi-1.0.1.5.dist-info}/licenses/LICENSE.md +0 -0
- {pyezvizapi-1.0.1.3.dist-info → pyezvizapi-1.0.1.5.dist-info}/top_level.txt +0 -0
pyezvizapi/__init__.py
CHANGED
|
@@ -19,6 +19,7 @@ from .constants import (
|
|
|
19
19
|
)
|
|
20
20
|
from .exceptions import (
|
|
21
21
|
AuthTestResultFailed,
|
|
22
|
+
DeviceException,
|
|
22
23
|
EzvizAuthTokenExpired,
|
|
23
24
|
EzvizAuthVerificationCode,
|
|
24
25
|
HTTPError,
|
|
@@ -37,6 +38,7 @@ __all__ = [
|
|
|
37
38
|
"BatteryCameraWorkMode",
|
|
38
39
|
"DefenseModeType",
|
|
39
40
|
"DeviceCatagories",
|
|
41
|
+
"DeviceException",
|
|
40
42
|
"DeviceSwitchType",
|
|
41
43
|
"DisplayMode",
|
|
42
44
|
"EzvizAuthTokenExpired",
|
pyezvizapi/api_endpoints.py
CHANGED
|
@@ -17,14 +17,16 @@ API_ENDPOINT_OSD = "/v3/userdevices/v1/devices/"
|
|
|
17
17
|
API_ENDPOINT_PANORAMIC_DEVICES_OPERATION = "/v3/panoramicDevices/operation"
|
|
18
18
|
API_ENDPOINT_UPGRADE_DEVICE = "/v3/upgrades/v1/devices/"
|
|
19
19
|
API_ENDPOINT_SEND_CODE = "/v3/sms/nologin/checkcode"
|
|
20
|
+
API_ENDPOINT_2FA_VALIDATE_POST_AUTH = "/v3/users/checkcode/mt"
|
|
20
21
|
API_ENDPOINT_UNIFIEDMSG_LIST_GET = "/v3/unifiedmsg/list"
|
|
21
22
|
API_ENDPOINT_IOT_FEATURE = "/v3/iot-feature/feature/"
|
|
23
|
+
API_ENDPOINT_IOT_ACTION = "/v3/iot-feature/action/"
|
|
22
24
|
API_ENDPOINT_CALLING_NOTIFY = "/v3/calling/"
|
|
23
25
|
|
|
24
26
|
API_ENDPOINT_ALARMINFO_GET = "/v3/alarms/v2/advanced"
|
|
25
27
|
API_ENDPOINT_V3_ALARMS = "/v3/alarms/"
|
|
26
28
|
API_ENDPOINT_SET_LUMINANCE = "/v3/alarms/device/alarmLight/"
|
|
27
|
-
API_ENDPOINT_REMOTE_UNLOCK = "/
|
|
29
|
+
API_ENDPOINT_REMOTE_UNLOCK = "/Video/1/DoorLockMgr/RemoteUnlockReq"
|
|
28
30
|
|
|
29
31
|
API_ENDPOINT_DEVCONFIG_BY_KEY = "/v3/devconfig/v1/keyValue/"
|
|
30
32
|
API_ENDPOINT_CAM_AUTH_CODE = "/v3/devconfig/authcode/query/"
|
pyezvizapi/client.py
CHANGED
|
@@ -13,6 +13,7 @@ from uuid import uuid4
|
|
|
13
13
|
import requests
|
|
14
14
|
|
|
15
15
|
from .api_endpoints import (
|
|
16
|
+
API_ENDPOINT_2FA_VALIDATE_POST_AUTH,
|
|
16
17
|
API_ENDPOINT_ALARM_SOUND,
|
|
17
18
|
API_ENDPOINT_ALARMINFO_GET,
|
|
18
19
|
API_ENDPOINT_CALLING_NOTIFY,
|
|
@@ -31,6 +32,7 @@ from .api_endpoints import (
|
|
|
31
32
|
API_ENDPOINT_DO_NOT_DISTURB,
|
|
32
33
|
API_ENDPOINT_GROUP_DEFENCE_MODE,
|
|
33
34
|
API_ENDPOINT_INTELLIGENT_APP,
|
|
35
|
+
API_ENDPOINT_IOT_ACTION,
|
|
34
36
|
API_ENDPOINT_IOT_FEATURE,
|
|
35
37
|
API_ENDPOINT_LOGIN,
|
|
36
38
|
API_ENDPOINT_LOGOUT,
|
|
@@ -38,9 +40,9 @@ from .api_endpoints import (
|
|
|
38
40
|
API_ENDPOINT_OSD,
|
|
39
41
|
API_ENDPOINT_PAGELIST,
|
|
40
42
|
API_ENDPOINT_PANORAMIC_DEVICES_OPERATION,
|
|
41
|
-
API_ENDPOINT_REMOTE_UNLOCK,
|
|
42
43
|
API_ENDPOINT_PTZCONTROL,
|
|
43
44
|
API_ENDPOINT_REFRESH_SESSION_ID,
|
|
45
|
+
API_ENDPOINT_REMOTE_UNLOCK,
|
|
44
46
|
API_ENDPOINT_RETURN_PANORAMIC,
|
|
45
47
|
API_ENDPOINT_SEND_CODE,
|
|
46
48
|
API_ENDPOINT_SERVER_INFO,
|
|
@@ -69,6 +71,7 @@ from .constants import (
|
|
|
69
71
|
MessageFilterType,
|
|
70
72
|
)
|
|
71
73
|
from .exceptions import (
|
|
74
|
+
DeviceException,
|
|
72
75
|
EzvizAuthTokenExpired,
|
|
73
76
|
EzvizAuthVerificationCode,
|
|
74
77
|
HTTPError,
|
|
@@ -1271,7 +1274,7 @@ class EzvizClient:
|
|
|
1271
1274
|
for item in devices.get("CLOUD", {})
|
|
1272
1275
|
if devices["CLOUD"][item].get("deviceSerial") == _serial
|
|
1273
1276
|
}
|
|
1274
|
-
_res_id = _res_id_list.pop() if
|
|
1277
|
+
_res_id = _res_id_list.pop() if _res_id_list else "NONE"
|
|
1275
1278
|
|
|
1276
1279
|
result[_serial] = {
|
|
1277
1280
|
"CLOUD": {_res_id: devices.get("CLOUD", {}).get(_res_id, {})},
|
|
@@ -1357,7 +1360,26 @@ class EzvizClient:
|
|
|
1357
1360
|
def get_cam_key(
|
|
1358
1361
|
self, serial: str, smscode: int | None = None, max_retries: int = 0
|
|
1359
1362
|
) -> Any:
|
|
1360
|
-
"""Get Camera encryption key. The key that is set after the camera is added to the account.
|
|
1363
|
+
"""Get Camera encryption key. The key that is set after the camera is added to the account.
|
|
1364
|
+
|
|
1365
|
+
Args:
|
|
1366
|
+
serial (str): The camera serial number.
|
|
1367
|
+
smscode (int | None): The 2FA code account when rights elevation is required.
|
|
1368
|
+
max_retries (int): The maximum number of retries. Defaults to 0.
|
|
1369
|
+
|
|
1370
|
+
Raises:
|
|
1371
|
+
PyEzvizError: If the camera encryption key can't be retrieved.
|
|
1372
|
+
EzvizAuthVerificationCode: If the account requires elevation with 2FA code.
|
|
1373
|
+
DeviceException: If the physical device is not reachable.
|
|
1374
|
+
|
|
1375
|
+
Returns:
|
|
1376
|
+
Any: JSON response, filtered to return encryptkey:
|
|
1377
|
+
{
|
|
1378
|
+
"resultCode": int, # Result code (0 if successful)
|
|
1379
|
+
"encryptkey": str, # Camera encryption key
|
|
1380
|
+
"resultDes": str # Status message in chinese
|
|
1381
|
+
}
|
|
1382
|
+
"""
|
|
1361
1383
|
|
|
1362
1384
|
if max_retries > MAX_RETRIES:
|
|
1363
1385
|
raise PyEzvizError("Can't gather proper data. Max retries exceeded.")
|
|
@@ -1401,6 +1423,9 @@ class EzvizClient:
|
|
|
1401
1423
|
if json_output["resultCode"] == "20002":
|
|
1402
1424
|
raise EzvizAuthVerificationCode(f"MFA code required: Got {json_output})")
|
|
1403
1425
|
|
|
1426
|
+
if json_output["resultCode"] == 2009:
|
|
1427
|
+
raise DeviceException(f"Device not reachable: Got {json_output})")
|
|
1428
|
+
|
|
1404
1429
|
if json_output["resultCode"] != "0":
|
|
1405
1430
|
if json_output["resultCode"] == "-1":
|
|
1406
1431
|
_LOGGER.warning(
|
|
@@ -1421,9 +1446,34 @@ class EzvizClient:
|
|
|
1421
1446
|
serial: str,
|
|
1422
1447
|
encrypt_pwd: str | None = None,
|
|
1423
1448
|
msg_auth_code: int | None = None,
|
|
1449
|
+
sender_type: int = 0,
|
|
1424
1450
|
max_retries: int = 0,
|
|
1425
1451
|
) -> Any:
|
|
1426
|
-
"""Get Camera auth code. This is the verification code on the camera sticker.
|
|
1452
|
+
"""Get Camera auth code. This is the verification code on the camera sticker.
|
|
1453
|
+
|
|
1454
|
+
Args:
|
|
1455
|
+
serial (str): The camera serial number.
|
|
1456
|
+
encrypt_pwd (str | None): This is always none.
|
|
1457
|
+
msg_auth_code (int | None): The 2FA code.
|
|
1458
|
+
sender_type (int): The sender type. Defaults to 0. Needs to be 3 when returning 2FA code.
|
|
1459
|
+
max_retries (int): The maximum number of retries. Defaults to 0.
|
|
1460
|
+
|
|
1461
|
+
Raises:
|
|
1462
|
+
PyEzvizError: If the camera auth code cannot be retrieved.
|
|
1463
|
+
EzvizAuthVerificationCode: If the operation requires elevation with 2FA.
|
|
1464
|
+
DeviceException: If the physical device is not reachable.
|
|
1465
|
+
|
|
1466
|
+
Returns:
|
|
1467
|
+
Any: JSON response, filtered to return devAuthCode:
|
|
1468
|
+
{
|
|
1469
|
+
"devAuthCode": str, # Device authorization code
|
|
1470
|
+
"meta": {
|
|
1471
|
+
"code": int, # Status code (200 if successful)
|
|
1472
|
+
"message": str, # Status message in chinese
|
|
1473
|
+
"moreInfo": null or {"INVALID_PARAMETER": str}
|
|
1474
|
+
}
|
|
1475
|
+
}
|
|
1476
|
+
"""
|
|
1427
1477
|
|
|
1428
1478
|
if max_retries > MAX_RETRIES:
|
|
1429
1479
|
raise PyEzvizError("Can't gather proper data. Max retries exceeded.")
|
|
@@ -1431,7 +1481,7 @@ class EzvizClient:
|
|
|
1431
1481
|
params: dict[str, int | str | None] = {
|
|
1432
1482
|
"encrptPwd": encrypt_pwd,
|
|
1433
1483
|
"msgAuthCode": msg_auth_code,
|
|
1434
|
-
"senderType":
|
|
1484
|
+
"senderType": sender_type,
|
|
1435
1485
|
}
|
|
1436
1486
|
|
|
1437
1487
|
try:
|
|
@@ -1464,13 +1514,88 @@ class EzvizClient:
|
|
|
1464
1514
|
+ str(req.text)
|
|
1465
1515
|
) from err
|
|
1466
1516
|
|
|
1517
|
+
if json_output["meta"]["code"] == 80000:
|
|
1518
|
+
raise EzvizAuthVerificationCode("Operation requires 2FA check")
|
|
1519
|
+
|
|
1520
|
+
if json_output["resultCode"] == 2009:
|
|
1521
|
+
raise DeviceException(f"Device not reachable: Got {json_output}")
|
|
1522
|
+
|
|
1467
1523
|
if json_output["meta"]["code"] != 200:
|
|
1468
1524
|
raise PyEzvizError(
|
|
1469
|
-
f"Could not get camera verification key: Got {json_output}
|
|
1525
|
+
f"Could not get camera verification key: Got {json_output}"
|
|
1470
1526
|
)
|
|
1471
1527
|
|
|
1472
1528
|
return json_output["devAuthCode"]
|
|
1473
1529
|
|
|
1530
|
+
def get_2fa_check_code(
|
|
1531
|
+
self,
|
|
1532
|
+
biz_type: str = "DEVICE_AUTH_CODE",
|
|
1533
|
+
username: str | None = None,
|
|
1534
|
+
max_retries: int = 0,
|
|
1535
|
+
) -> Any:
|
|
1536
|
+
"""Initiate 2FA check for sensitive operations. Elevates your session token permission.
|
|
1537
|
+
|
|
1538
|
+
Args:
|
|
1539
|
+
biz_type (str): The operation type. (DEVICE_ENCRYPTION | DEVICE_AUTH_CODE)
|
|
1540
|
+
username (str): The account username.
|
|
1541
|
+
max_retries (int): The maximum number of retries. Defaults to 0.
|
|
1542
|
+
|
|
1543
|
+
Raises:
|
|
1544
|
+
PyEzvizError: If the operation fails.
|
|
1545
|
+
|
|
1546
|
+
Returns:
|
|
1547
|
+
Any: JSON response with the following structure:
|
|
1548
|
+
{
|
|
1549
|
+
"meta": {
|
|
1550
|
+
"code": int, # Status code (200 if successful)
|
|
1551
|
+
"message": str # Status message in chinese
|
|
1552
|
+
"moreInfo": null
|
|
1553
|
+
},
|
|
1554
|
+
"contact": {
|
|
1555
|
+
"type": str, # 2FA code will be sent to this (EMAIL)
|
|
1556
|
+
"fuzzyContact": str # Destination value (e.g., someone@email.local)
|
|
1557
|
+
}
|
|
1558
|
+
}
|
|
1559
|
+
"""
|
|
1560
|
+
|
|
1561
|
+
if max_retries > MAX_RETRIES:
|
|
1562
|
+
raise PyEzvizError("Can't gather proper data. Max retries exceeded.")
|
|
1563
|
+
|
|
1564
|
+
try:
|
|
1565
|
+
req = self._session.post(
|
|
1566
|
+
url=f"https://{self._token['api_url']}{API_ENDPOINT_2FA_VALIDATE_POST_AUTH}",
|
|
1567
|
+
data={"bizType": biz_type, "from": username},
|
|
1568
|
+
timeout=self._timeout,
|
|
1569
|
+
)
|
|
1570
|
+
|
|
1571
|
+
req.raise_for_status()
|
|
1572
|
+
|
|
1573
|
+
except requests.HTTPError as err:
|
|
1574
|
+
if err.response.status_code == 401:
|
|
1575
|
+
# session is wrong, need to relogin
|
|
1576
|
+
self.login()
|
|
1577
|
+
return self.get_2fa_check_code(biz_type, username, max_retries + 1)
|
|
1578
|
+
|
|
1579
|
+
raise HTTPError from err
|
|
1580
|
+
|
|
1581
|
+
try:
|
|
1582
|
+
json_output = req.json()
|
|
1583
|
+
|
|
1584
|
+
except ValueError as err:
|
|
1585
|
+
raise PyEzvizError(
|
|
1586
|
+
"Impossible to decode response: "
|
|
1587
|
+
+ str(err)
|
|
1588
|
+
+ "\nResponse was: "
|
|
1589
|
+
+ str(req.text)
|
|
1590
|
+
) from err
|
|
1591
|
+
|
|
1592
|
+
if json_output["meta"]["code"] != 200:
|
|
1593
|
+
raise PyEzvizError(
|
|
1594
|
+
f"Could not request elevated permission: Got {json_output})"
|
|
1595
|
+
)
|
|
1596
|
+
|
|
1597
|
+
return json_output
|
|
1598
|
+
|
|
1474
1599
|
def create_panoramic(self, serial: str, max_retries: int = 0) -> Any:
|
|
1475
1600
|
"""Create panoramic image."""
|
|
1476
1601
|
|
|
@@ -1611,26 +1736,38 @@ class EzvizClient:
|
|
|
1611
1736
|
|
|
1612
1737
|
return True
|
|
1613
1738
|
|
|
1614
|
-
def remote_unlock(self, serial: str, lock_no: int) -> bool:
|
|
1615
|
-
"""Sends a remote command to unlock a specific lock.
|
|
1616
|
-
try:
|
|
1617
|
-
endpoint = API_ENDPOINT_REMOTE_UNLOCK.replace("#SERIAL#", serial)
|
|
1618
|
-
user_id = self._token["username"]
|
|
1619
|
-
payload = json.dumps({
|
|
1620
|
-
"unLockInfo": {
|
|
1621
|
-
"bindCode": f"{FEATURE_CODE}{user_id}",
|
|
1622
|
-
"lockNo": lock_no,
|
|
1623
|
-
"streamToken": "",
|
|
1624
|
-
"userName": user_id,
|
|
1625
|
-
}
|
|
1626
|
-
})
|
|
1739
|
+
def remote_unlock(self, serial: str, user_id: str, lock_no: int) -> bool:
|
|
1740
|
+
"""Sends a remote command to unlock a specific lock.
|
|
1627
1741
|
|
|
1742
|
+
Args:
|
|
1743
|
+
serial (str): The camera serial.
|
|
1744
|
+
user_id (str): The user id.
|
|
1745
|
+
lock_no (int): The lock number.
|
|
1746
|
+
|
|
1747
|
+
Raises:
|
|
1748
|
+
PyEzvizError: If max retries are exceeded or if the response indicates failure.
|
|
1749
|
+
HTTPError: If an HTTP error occurs (other than a 401, which triggers re-login).
|
|
1750
|
+
|
|
1751
|
+
Returns:
|
|
1752
|
+
bool: True if the operation was successful.
|
|
1753
|
+
|
|
1754
|
+
"""
|
|
1755
|
+
try:
|
|
1628
1756
|
headers = self._session.headers
|
|
1629
1757
|
headers.update({"Content-Type": "application/json"})
|
|
1630
1758
|
|
|
1631
1759
|
req = self._session.put(
|
|
1632
|
-
url=f"https://{self._token['api_url']}{
|
|
1633
|
-
data=
|
|
1760
|
+
url=f"https://{self._token['api_url']}{API_ENDPOINT_IOT_ACTION}{serial}{API_ENDPOINT_REMOTE_UNLOCK}",
|
|
1761
|
+
data=json.dumps(
|
|
1762
|
+
{
|
|
1763
|
+
"unLockInfo": {
|
|
1764
|
+
"bindCode": f"{FEATURE_CODE}{user_id}",
|
|
1765
|
+
"lockNo": lock_no,
|
|
1766
|
+
"streamToken": "",
|
|
1767
|
+
"userName": user_id,
|
|
1768
|
+
}
|
|
1769
|
+
}
|
|
1770
|
+
),
|
|
1634
1771
|
timeout=self._timeout,
|
|
1635
1772
|
headers=headers,
|
|
1636
1773
|
)
|
pyezvizapi/exceptions.py
CHANGED
|
@@ -27,3 +27,7 @@ class EzvizAuthTokenExpired(PyEzvizError):
|
|
|
27
27
|
|
|
28
28
|
class EzvizAuthVerificationCode(PyEzvizError):
|
|
29
29
|
"""Authentication failed because MFA verification code is required."""
|
|
30
|
+
|
|
31
|
+
|
|
32
|
+
class DeviceException(PyEzvizError):
|
|
33
|
+
"""The device network is abnormal, please check the device network or try again."""
|
|
@@ -1,19 +1,19 @@
|
|
|
1
|
-
pyezvizapi/__init__.py,sha256=
|
|
1
|
+
pyezvizapi/__init__.py,sha256=yWITfZOi5zvKblfaeB2ft-wXYmZ2NviYVq_tsK8YkSk,1334
|
|
2
2
|
pyezvizapi/__main__.py,sha256=OsawbYa-eoLUTOMr4xWeryq4sDzs09WL9GELKQTbda8,16396
|
|
3
|
-
pyezvizapi/api_endpoints.py,sha256=
|
|
3
|
+
pyezvizapi/api_endpoints.py,sha256=rk6VinLVCn-B6DxnhfV79liplNpgUsipNbTEa_MRVwU,2755
|
|
4
4
|
pyezvizapi/camera.py,sha256=BpmLySbnWWEKimSwgjx_cB60Q-6dbgdY-NA--NzUvps,11486
|
|
5
5
|
pyezvizapi/cas.py,sha256=d31ZflYSD9P40MnsNRNZbT0HVLvlnHokKpLbdAjWQ74,5631
|
|
6
|
-
pyezvizapi/client.py,sha256
|
|
6
|
+
pyezvizapi/client.py,sha256=6NfWGAYalInpIlmsbraEK_CUyR1CMGIw4jqhKQUfkk8,85561
|
|
7
7
|
pyezvizapi/constants.py,sha256=jjLO-Ne9jq9m9_giYB4rnPXDZKkzKhesVXBqP1B3-00,12304
|
|
8
|
-
pyezvizapi/exceptions.py,sha256=
|
|
8
|
+
pyezvizapi/exceptions.py,sha256=28lLyM0ILTRHgWqr9D-DqqKFXx7POuF0WAZctdC8Kbc,735
|
|
9
9
|
pyezvizapi/light_bulb.py,sha256=ADLrPZ6NL4vANzmohU63QuD9qVGkKHkX9C0o7Evbv-A,5730
|
|
10
10
|
pyezvizapi/mqtt.py,sha256=Y4X99Z0Avm32SE8vog7CNsv6tGUPmPYUZUgPDGS0QJA,7866
|
|
11
11
|
pyezvizapi/test_cam_rtsp.py,sha256=w7GPcYIeK78TxL8zFDihdGSDQNWcYrurwZOr6uFzzgo,4902
|
|
12
12
|
pyezvizapi/utils.py,sha256=5J10o3h-y8prWDvl3LSAF-9wS1jBgBMg5cpAEebcuSM,4936
|
|
13
|
-
pyezvizapi-1.0.1.
|
|
14
|
-
pyezvizapi-1.0.1.
|
|
15
|
-
pyezvizapi-1.0.1.
|
|
16
|
-
pyezvizapi-1.0.1.
|
|
17
|
-
pyezvizapi-1.0.1.
|
|
18
|
-
pyezvizapi-1.0.1.
|
|
19
|
-
pyezvizapi-1.0.1.
|
|
13
|
+
pyezvizapi-1.0.1.5.dist-info/licenses/LICENSE,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
14
|
+
pyezvizapi-1.0.1.5.dist-info/licenses/LICENSE.md,sha256=xx0jnfkXJvxRnG63LTGOxlggYnIysveWIZ6H3PNdCrQ,11357
|
|
15
|
+
pyezvizapi-1.0.1.5.dist-info/METADATA,sha256=ZHsHhFN88VbuD53CDJcFslvEzDTR_TQaDAlHf9PKVhc,694
|
|
16
|
+
pyezvizapi-1.0.1.5.dist-info/WHEEL,sha256=_zCd3N1l69ArxyTb8rzEoP9TpbYXkqRFSNOD5OuxnTs,91
|
|
17
|
+
pyezvizapi-1.0.1.5.dist-info/entry_points.txt,sha256=_BSJ3eNb2H_AZkRdsv1s4mojqWn3N7m503ujvg1SudA,56
|
|
18
|
+
pyezvizapi-1.0.1.5.dist-info/top_level.txt,sha256=gMZTelIi8z7pXyTCQLLaIkxVRrDQ_lS2NEv0WgfHrHs,11
|
|
19
|
+
pyezvizapi-1.0.1.5.dist-info/RECORD,,
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|
|
File without changes
|