axis 50__tar.gz → 52__tar.gz

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (108) hide show
  1. {axis-50 → axis-52}/PKG-INFO +3 -3
  2. {axis-50 → axis-52}/axis/vapix/models/parameters/ptz.py +39 -39
  3. {axis-50 → axis-52}/axis/vapix/models/port_management.py +1 -1
  4. {axis-50 → axis-52}/axis.egg-info/PKG-INFO +3 -3
  5. {axis-50 → axis-52}/axis.egg-info/requires.txt +1 -1
  6. {axis-50 → axis-52}/pyproject.toml +2 -2
  7. {axis-50 → axis-52}/setup.py +1 -1
  8. {axis-50 → axis-52}/tests/test_port_management.py +17 -0
  9. {axis-50 → axis-52}/LICENSE +0 -0
  10. {axis-50 → axis-52}/README.md +0 -0
  11. {axis-50 → axis-52}/axis/__init__.py +0 -0
  12. {axis-50 → axis-52}/axis/__main__.py +0 -0
  13. {axis-50 → axis-52}/axis/configuration.py +0 -0
  14. {axis-50 → axis-52}/axis/device.py +0 -0
  15. {axis-50 → axis-52}/axis/errors.py +0 -0
  16. {axis-50 → axis-52}/axis/event_stream.py +0 -0
  17. {axis-50 → axis-52}/axis/models/__init__.py +0 -0
  18. {axis-50 → axis-52}/axis/models/event.py +0 -0
  19. {axis-50 → axis-52}/axis/py.typed +0 -0
  20. {axis-50 → axis-52}/axis/rtsp.py +0 -0
  21. {axis-50 → axis-52}/axis/stream_manager.py +0 -0
  22. {axis-50 → axis-52}/axis/vapix/__init__.py +0 -0
  23. {axis-50 → axis-52}/axis/vapix/interfaces/__init__.py +0 -0
  24. {axis-50 → axis-52}/axis/vapix/interfaces/api_discovery.py +0 -0
  25. {axis-50 → axis-52}/axis/vapix/interfaces/api_handler.py +0 -0
  26. {axis-50 → axis-52}/axis/vapix/interfaces/applications/__init__.py +0 -0
  27. {axis-50 → axis-52}/axis/vapix/interfaces/applications/application_handler.py +0 -0
  28. {axis-50 → axis-52}/axis/vapix/interfaces/applications/applications.py +0 -0
  29. {axis-50 → axis-52}/axis/vapix/interfaces/applications/fence_guard.py +0 -0
  30. {axis-50 → axis-52}/axis/vapix/interfaces/applications/loitering_guard.py +0 -0
  31. {axis-50 → axis-52}/axis/vapix/interfaces/applications/motion_guard.py +0 -0
  32. {axis-50 → axis-52}/axis/vapix/interfaces/applications/object_analytics.py +0 -0
  33. {axis-50 → axis-52}/axis/vapix/interfaces/applications/vmd4.py +0 -0
  34. {axis-50 → axis-52}/axis/vapix/interfaces/basic_device_info.py +0 -0
  35. {axis-50 → axis-52}/axis/vapix/interfaces/event_instances.py +0 -0
  36. {axis-50 → axis-52}/axis/vapix/interfaces/light_control.py +0 -0
  37. {axis-50 → axis-52}/axis/vapix/interfaces/mqtt.py +0 -0
  38. {axis-50 → axis-52}/axis/vapix/interfaces/parameters/__init__.py +0 -0
  39. {axis-50 → axis-52}/axis/vapix/interfaces/parameters/brand.py +0 -0
  40. {axis-50 → axis-52}/axis/vapix/interfaces/parameters/image.py +0 -0
  41. {axis-50 → axis-52}/axis/vapix/interfaces/parameters/io_port.py +0 -0
  42. {axis-50 → axis-52}/axis/vapix/interfaces/parameters/param_cgi.py +0 -0
  43. {axis-50 → axis-52}/axis/vapix/interfaces/parameters/param_handler.py +0 -0
  44. {axis-50 → axis-52}/axis/vapix/interfaces/parameters/properties.py +0 -0
  45. {axis-50 → axis-52}/axis/vapix/interfaces/parameters/ptz.py +0 -0
  46. {axis-50 → axis-52}/axis/vapix/interfaces/parameters/stream_profile.py +0 -0
  47. {axis-50 → axis-52}/axis/vapix/interfaces/pir_sensor_configuration.py +0 -0
  48. {axis-50 → axis-52}/axis/vapix/interfaces/port_cgi.py +0 -0
  49. {axis-50 → axis-52}/axis/vapix/interfaces/port_management.py +0 -0
  50. {axis-50 → axis-52}/axis/vapix/interfaces/ptz.py +0 -0
  51. {axis-50 → axis-52}/axis/vapix/interfaces/pwdgrp_cgi.py +0 -0
  52. {axis-50 → axis-52}/axis/vapix/interfaces/stream_profiles.py +0 -0
  53. {axis-50 → axis-52}/axis/vapix/interfaces/user_groups.py +0 -0
  54. {axis-50 → axis-52}/axis/vapix/interfaces/view_areas.py +0 -0
  55. {axis-50 → axis-52}/axis/vapix/models/__init__.py +0 -0
  56. {axis-50 → axis-52}/axis/vapix/models/api.py +0 -0
  57. {axis-50 → axis-52}/axis/vapix/models/api_discovery.py +0 -0
  58. {axis-50 → axis-52}/axis/vapix/models/applications/__init__.py +0 -0
  59. {axis-50 → axis-52}/axis/vapix/models/applications/application.py +0 -0
  60. {axis-50 → axis-52}/axis/vapix/models/applications/fence_guard.py +0 -0
  61. {axis-50 → axis-52}/axis/vapix/models/applications/loitering_guard.py +0 -0
  62. {axis-50 → axis-52}/axis/vapix/models/applications/motion_guard.py +0 -0
  63. {axis-50 → axis-52}/axis/vapix/models/applications/object_analytics.py +0 -0
  64. {axis-50 → axis-52}/axis/vapix/models/applications/vmd4.py +0 -0
  65. {axis-50 → axis-52}/axis/vapix/models/basic_device_info.py +0 -0
  66. {axis-50 → axis-52}/axis/vapix/models/event_instance.py +0 -0
  67. {axis-50 → axis-52}/axis/vapix/models/light_control.py +0 -0
  68. {axis-50 → axis-52}/axis/vapix/models/mqtt.py +0 -0
  69. {axis-50 → axis-52}/axis/vapix/models/parameters/__init__.py +0 -0
  70. {axis-50 → axis-52}/axis/vapix/models/parameters/brand.py +0 -0
  71. {axis-50 → axis-52}/axis/vapix/models/parameters/image.py +0 -0
  72. {axis-50 → axis-52}/axis/vapix/models/parameters/io_port.py +0 -0
  73. {axis-50 → axis-52}/axis/vapix/models/parameters/param_cgi.py +0 -0
  74. {axis-50 → axis-52}/axis/vapix/models/parameters/properties.py +0 -0
  75. {axis-50 → axis-52}/axis/vapix/models/parameters/stream_profile.py +0 -0
  76. {axis-50 → axis-52}/axis/vapix/models/pir_sensor_configuration.py +0 -0
  77. {axis-50 → axis-52}/axis/vapix/models/port_cgi.py +0 -0
  78. {axis-50 → axis-52}/axis/vapix/models/ptz_cgi.py +0 -0
  79. {axis-50 → axis-52}/axis/vapix/models/pwdgrp_cgi.py +0 -0
  80. {axis-50 → axis-52}/axis/vapix/models/stream_profile.py +0 -0
  81. {axis-50 → axis-52}/axis/vapix/models/user_group.py +0 -0
  82. {axis-50 → axis-52}/axis/vapix/models/view_area.py +0 -0
  83. {axis-50 → axis-52}/axis/vapix/vapix.py +0 -0
  84. {axis-50 → axis-52}/axis.egg-info/SOURCES.txt +0 -0
  85. {axis-50 → axis-52}/axis.egg-info/dependency_links.txt +0 -0
  86. {axis-50 → axis-52}/axis.egg-info/entry_points.txt +0 -0
  87. {axis-50 → axis-52}/axis.egg-info/top_level.txt +0 -0
  88. {axis-50 → axis-52}/setup.cfg +0 -0
  89. {axis-50 → axis-52}/tests/test_api_discovery.py +0 -0
  90. {axis-50 → axis-52}/tests/test_api_handler.py +0 -0
  91. {axis-50 → axis-52}/tests/test_basic_device_info.py +0 -0
  92. {axis-50 → axis-52}/tests/test_configuration.py +0 -0
  93. {axis-50 → axis-52}/tests/test_device.py +0 -0
  94. {axis-50 → axis-52}/tests/test_event.py +0 -0
  95. {axis-50 → axis-52}/tests/test_event_instances.py +0 -0
  96. {axis-50 → axis-52}/tests/test_event_stream.py +0 -0
  97. {axis-50 → axis-52}/tests/test_light_control.py +0 -0
  98. {axis-50 → axis-52}/tests/test_mqtt.py +0 -0
  99. {axis-50 → axis-52}/tests/test_pir_sensor_configuration.py +0 -0
  100. {axis-50 → axis-52}/tests/test_port_cgi.py +0 -0
  101. {axis-50 → axis-52}/tests/test_ptz.py +0 -0
  102. {axis-50 → axis-52}/tests/test_pwdgrp_cgi.py +0 -0
  103. {axis-50 → axis-52}/tests/test_rtsp.py +0 -0
  104. {axis-50 → axis-52}/tests/test_stream_manager.py +0 -0
  105. {axis-50 → axis-52}/tests/test_stream_profiles.py +0 -0
  106. {axis-50 → axis-52}/tests/test_user_groups.py +0 -0
  107. {axis-50 → axis-52}/tests/test_vapix.py +0 -0
  108. {axis-50 → axis-52}/tests/test_view_areas.py +0 -0
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: axis
3
- Version: 50
3
+ Version: 52
4
4
  Summary: A Python library for communicating with devices from Axis Communications
5
5
  Home-page: https://github.com/Kane610/axis
6
- Download-URL: https://github.com/Kane610/axis/archive/v50.tar.gz
6
+ Download-URL: https://github.com/Kane610/axis/archive/v52.tar.gz
7
7
  Author: Robert Svensson
8
8
  Author-email: Robert Svensson <Kane610@users.noreply.github.com>
9
9
  License: MIT
@@ -36,7 +36,7 @@ Requires-Dist: pytest-aiohttp==1.0.5; extra == "requirements-test"
36
36
  Requires-Dist: pytest-asyncio==0.23.5; extra == "requirements-test"
37
37
  Requires-Dist: pytest-cov==4.1.0; extra == "requirements-test"
38
38
  Requires-Dist: respx==0.20.2; extra == "requirements-test"
39
- Requires-Dist: ruff==0.3.0; extra == "requirements-test"
39
+ Requires-Dist: ruff==0.3.1; extra == "requirements-test"
40
40
  Requires-Dist: types-orjson==3.6.2; extra == "requirements-test"
41
41
  Requires-Dist: types-xmltodict==v0.13.0.3; extra == "requirements-test"
42
42
  Provides-Extra: requirements-dev
@@ -18,18 +18,18 @@ class PtzLimitParamT(TypedDict):
18
18
  """PTZ limit data description."""
19
19
 
20
20
  MaxBrightness: NotRequired[int]
21
- MaxFieldAngle: int
21
+ MaxFieldAngle: NotRequired[int]
22
22
  MaxFocus: NotRequired[int]
23
23
  MaxIris: NotRequired[int]
24
- MaxPan: int
25
- MaxTilt: int
24
+ MaxPan: NotRequired[int]
25
+ MaxTilt: NotRequired[int]
26
26
  MaxZoom: int
27
27
  MinBrightness: NotRequired[int]
28
28
  MinFieldAngle: int
29
29
  MinFocus: NotRequired[int]
30
30
  MinIris: NotRequired[int]
31
- MinPan: int
32
- MinTilt: int
31
+ MinPan: NotRequired[int]
32
+ MinTilt: NotRequired[int]
33
33
  MinZoom: int
34
34
 
35
35
 
@@ -113,12 +113,12 @@ class PtzVariousParamT(TypedDict):
113
113
  CtlQueuePollTime: int
114
114
  HomePresetSet: bool
115
115
  Locked: NotRequired[bool]
116
- MaxProportionalSpeed: int
117
- PanEnabled: bool
118
- ProportionalSpeedEnabled: bool
116
+ MaxProportionalSpeed: NotRequired[int]
117
+ PanEnabled: NotRequired[bool]
118
+ ProportionalSpeedEnabled: NotRequired[bool]
119
119
  ReturnToOverview: int
120
- SpeedCtlEnabled: bool
121
- TiltEnabled: bool
120
+ SpeedCtlEnabled: NotRequired[bool]
121
+ TiltEnabled: NotRequired[bool]
122
122
  ZoomEnabled: bool
123
123
 
124
124
 
@@ -131,13 +131,13 @@ class PtzParamT(TypedDict):
131
131
  NbrOfSerPorts: int
132
132
  CamPorts: dict[str, int]
133
133
  ImageSource: dict[str, PtzImageSourceParamT]
134
- Limit: dict[str, PtzLimitParamT]
134
+ Limit: NotRequired[dict[str, PtzLimitParamT]]
135
135
  Preset: dict[str, PtzPresetParamT]
136
136
  PTZDriverStatuses: dict[str, int]
137
- Support: dict[str, PtzSupportParamT]
137
+ Support: NotRequired[dict[str, PtzSupportParamT]]
138
138
  UserAdv: dict[str, PtzUserAdvParamT]
139
139
  UserCtlQueue: dict[str, PtzUserCtlQueueParamT]
140
- Various: dict[str, PtzVariousParamT]
140
+ Various: NotRequired[dict[str, PtzVariousParamT]]
141
141
 
142
142
 
143
143
  @dataclass
@@ -170,39 +170,39 @@ class PtzLimit:
170
170
  The purpose of those two parameters is to calibrate image centering.
171
171
  """
172
172
 
173
- max_field_angle: int
174
- min_field_angle: int
175
- max_pan: int
176
- min_pan: int
177
- max_tilt: int
178
- min_tilt: int
179
173
  max_zoom: int
180
174
  min_zoom: int
181
175
  max_brightness: int | None
182
176
  min_brightness: int | None
177
+ max_field_angle: int | None
178
+ min_field_angle: int | None
183
179
  max_focus: int | None
184
180
  min_focus: int | None
185
181
  max_iris: int | None
186
182
  min_iris: int | None
183
+ max_pan: int | None
184
+ min_pan: int | None
185
+ max_tilt: int | None
186
+ min_tilt: int | None
187
187
 
188
188
  @classmethod
189
189
  def decode(cls, data: PtzLimitParamT) -> Self:
190
190
  """Decode dictionary to class object."""
191
191
  return cls(
192
- max_field_angle=data["MaxFieldAngle"],
193
- min_field_angle=data["MinFieldAngle"],
194
- max_pan=data["MaxPan"],
195
- min_pan=data["MinPan"],
196
- max_tilt=data["MaxTilt"],
197
- min_tilt=data["MinTilt"],
198
192
  max_zoom=data["MaxZoom"],
199
193
  min_zoom=data["MinZoom"],
200
194
  max_brightness=data.get("MaxBrightness"),
201
195
  min_brightness=data.get("MinBrightness"),
196
+ max_field_angle=data.get("MaxFieldAngle"),
197
+ min_field_angle=data.get("MinFieldAngle"),
202
198
  max_focus=data.get("MaxFocus"),
203
199
  min_focus=data.get("MinFocus"),
204
200
  max_iris=data.get("MaxIris"),
205
201
  min_iris=data.get("MinIris"),
202
+ max_pan=data.get("MaxPan"),
203
+ min_pan=data.get("MinPan"),
204
+ max_tilt=data.get("MaxTilt"),
205
+ min_tilt=data.get("MinTilt"),
206
206
  )
207
207
 
208
208
  @classmethod
@@ -322,12 +322,12 @@ class PtzVarious:
322
322
  control_queue_poll_time: int
323
323
  home_preset_set: bool
324
324
  locked: bool
325
- max_proportional_speed: int
326
- pan_enabled: bool
327
- proportional_speed_enabled: bool
325
+ max_proportional_speed: int | None
326
+ pan_enabled: bool | None
327
+ proportional_speed_enabled: bool | None
328
328
  return_to_overview: int
329
- speed_control_enabled: bool
330
- tilt_enabled: bool
329
+ speed_control_enabled: bool | None
330
+ tilt_enabled: bool | None
331
331
  zoom_enabled: bool
332
332
 
333
333
  @classmethod
@@ -339,12 +339,12 @@ class PtzVarious:
339
339
  control_queue_poll_time=data["CtlQueuePollTime"],
340
340
  home_preset_set=data["HomePresetSet"],
341
341
  locked=data.get("Locked", False),
342
- max_proportional_speed=data["MaxProportionalSpeed"],
343
- pan_enabled=data["PanEnabled"],
344
- proportional_speed_enabled=data["ProportionalSpeedEnabled"],
342
+ max_proportional_speed=data.get("MaxProportionalSpeed"),
343
+ pan_enabled=data.get("PanEnabled"),
344
+ proportional_speed_enabled=data.get("ProportionalSpeedEnabled"),
345
345
  return_to_overview=data["ReturnToOverview"],
346
- speed_control_enabled=data["SpeedCtlEnabled"],
347
- tilt_enabled=data["TiltEnabled"],
346
+ speed_control_enabled=data.get("SpeedCtlEnabled"),
347
+ tilt_enabled=data.get("TiltEnabled"),
348
348
  zoom_enabled=data["ZoomEnabled"],
349
349
  )
350
350
 
@@ -389,11 +389,11 @@ class PtzParam(ParamItem):
389
389
  return cls(
390
390
  id="ptz",
391
391
  camera_default=data["CameraDefault"],
392
- number_of_cameras=data["NbrOfCameras"],
392
+ number_of_cameras=data.get("NbrOfCameras", 1),
393
393
  number_of_serial_ports=data["NbrOfSerPorts"],
394
394
  cam_ports=data["CamPorts"],
395
395
  image_source=PtzImageSource.from_dict(data["ImageSource"]),
396
- limits=PtzLimit.from_dict(data["Limit"]),
397
- support=PtzSupport.from_dict(data["Support"]),
398
- various=PtzVarious.from_dict(data["Various"]),
396
+ limits=PtzLimit.from_dict(data.get("Limit", {})),
397
+ support=PtzSupport.from_dict(data.get("Support", {})),
398
+ various=PtzVarious.from_dict(data.get("Various", {})),
399
399
  )
@@ -218,7 +218,7 @@ class GetPortsResponse(ApiResponse[dict[str, Port]]):
218
218
  api_version=data["apiVersion"],
219
219
  context=data["context"],
220
220
  method=data["method"],
221
- data=Port.decode_to_dict(data["data"]["items"]),
221
+ data=Port.decode_to_dict(data["data"].get("items", [])),
222
222
  )
223
223
 
224
224
 
@@ -1,9 +1,9 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: axis
3
- Version: 50
3
+ Version: 52
4
4
  Summary: A Python library for communicating with devices from Axis Communications
5
5
  Home-page: https://github.com/Kane610/axis
6
- Download-URL: https://github.com/Kane610/axis/archive/v50.tar.gz
6
+ Download-URL: https://github.com/Kane610/axis/archive/v52.tar.gz
7
7
  Author: Robert Svensson
8
8
  Author-email: Robert Svensson <Kane610@users.noreply.github.com>
9
9
  License: MIT
@@ -36,7 +36,7 @@ Requires-Dist: pytest-aiohttp==1.0.5; extra == "requirements-test"
36
36
  Requires-Dist: pytest-asyncio==0.23.5; extra == "requirements-test"
37
37
  Requires-Dist: pytest-cov==4.1.0; extra == "requirements-test"
38
38
  Requires-Dist: respx==0.20.2; extra == "requirements-test"
39
- Requires-Dist: ruff==0.3.0; extra == "requirements-test"
39
+ Requires-Dist: ruff==0.3.1; extra == "requirements-test"
40
40
  Requires-Dist: types-orjson==3.6.2; extra == "requirements-test"
41
41
  Requires-Dist: types-xmltodict==v0.13.0.3; extra == "requirements-test"
42
42
  Provides-Extra: requirements-dev
@@ -19,6 +19,6 @@ pytest-aiohttp==1.0.5
19
19
  pytest-asyncio==0.23.5
20
20
  pytest-cov==4.1.0
21
21
  respx==0.20.2
22
- ruff==0.3.0
22
+ ruff==0.3.1
23
23
  types-orjson==3.6.2
24
24
  types-xmltodict==v0.13.0.3
@@ -4,7 +4,7 @@ build-backend = "setuptools.build_meta"
4
4
 
5
5
  [project]
6
6
  name = "axis"
7
- version = "50"
7
+ version = "52"
8
8
  license = {text = "MIT"}
9
9
  description = "A Python library for communicating with devices from Axis Communications"
10
10
  readme = "README.md"
@@ -40,7 +40,7 @@ requirements_test = [
40
40
  "pytest-asyncio==0.23.5",
41
41
  "pytest-cov==4.1.0",
42
42
  "respx==0.20.2",
43
- "ruff==0.3.0",
43
+ "ruff==0.3.1",
44
44
  "types-orjson==3.6.2",
45
45
  "types-xmltodict==v0.13.0.3",
46
46
  ]
@@ -4,7 +4,7 @@ from setuptools import find_packages, setup
4
4
 
5
5
  MIN_PY_VERSION = "3.11"
6
6
  PACKAGES = find_packages(exclude=["tests", "tests.*"])
7
- VERSION = "50"
7
+ VERSION = "52"
8
8
 
9
9
  setup(
10
10
  name="axis",
@@ -71,6 +71,16 @@ async def test_get_ports(respx_mock, io_port_management):
71
71
  }
72
72
 
73
73
 
74
+ async def test_get_empty_ports_response(respx_mock, io_port_management):
75
+ """Test get_ports call."""
76
+ respx_mock.post("/axis-cgi/io/portmanagement.cgi").respond(
77
+ json=GET_EMPTY_PORTS_RESPONSE,
78
+ )
79
+ await io_port_management.update()
80
+ assert io_port_management.initialized
81
+ assert len(io_port_management.values()) == 0
82
+
83
+
74
84
  async def test_set_ports(respx_mock, io_port_management):
75
85
  """Test set_ports call."""
76
86
  route = respx_mock.post("/axis-cgi/io/portmanagement.cgi")
@@ -171,6 +181,13 @@ GET_PORTS_RESPONSE = {
171
181
  },
172
182
  }
173
183
 
184
+ GET_EMPTY_PORTS_RESPONSE = {
185
+ "apiVersion": "1.0",
186
+ "context": "Axis library",
187
+ "method": "getPorts",
188
+ "data": {"numberOfPorts": 0},
189
+ }
190
+
174
191
  GET_SUPPORTED_VERSIONS_RESPONSE = {
175
192
  "apiVersion": "1.0",
176
193
  "context": "",
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes
File without changes