uiprotect 1.7.1__tar.gz → 1.8.0__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.

Potentially problematic release.


This version of uiprotect might be problematic. Click here for more details.

Files changed (36) hide show
  1. {uiprotect-1.7.1 → uiprotect-1.8.0}/PKG-INFO +1 -1
  2. {uiprotect-1.7.1 → uiprotect-1.8.0}/pyproject.toml +1 -1
  3. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/data/base.py +16 -19
  4. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/data/bootstrap.py +4 -9
  5. {uiprotect-1.7.1 → uiprotect-1.8.0}/LICENSE +0 -0
  6. {uiprotect-1.7.1 → uiprotect-1.8.0}/README.md +0 -0
  7. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/__init__.py +0 -0
  8. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/__main__.py +0 -0
  9. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/api.py +0 -0
  10. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/cli/__init__.py +0 -0
  11. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/cli/backup.py +0 -0
  12. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/cli/base.py +0 -0
  13. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/cli/cameras.py +0 -0
  14. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/cli/chimes.py +0 -0
  15. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/cli/doorlocks.py +0 -0
  16. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/cli/events.py +0 -0
  17. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/cli/lights.py +0 -0
  18. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/cli/liveviews.py +0 -0
  19. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/cli/nvr.py +0 -0
  20. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/cli/sensors.py +0 -0
  21. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/cli/viewers.py +0 -0
  22. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/data/__init__.py +0 -0
  23. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/data/convert.py +0 -0
  24. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/data/devices.py +0 -0
  25. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/data/nvr.py +0 -0
  26. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/data/types.py +0 -0
  27. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/data/user.py +0 -0
  28. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/data/websocket.py +0 -0
  29. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/exceptions.py +0 -0
  30. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/py.typed +0 -0
  31. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/release_cache.json +0 -0
  32. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/stream.py +0 -0
  33. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/test_util/__init__.py +0 -0
  34. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/test_util/anonymize.py +0 -0
  35. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/utils.py +0 -0
  36. {uiprotect-1.7.1 → uiprotect-1.8.0}/src/uiprotect/websocket.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: uiprotect
3
- Version: 1.7.1
3
+ Version: 1.8.0
4
4
  Summary: Python API for Unifi Protect (Unofficial)
5
5
  Home-page: https://github.com/uilibs/uiprotect
6
6
  License: MIT
@@ -1,6 +1,6 @@
1
1
  [tool.poetry]
2
2
  name = "uiprotect"
3
- version = "1.7.1"
3
+ version = "1.8.0"
4
4
  description = "Python API for Unifi Protect (Unofficial)"
5
5
  authors = ["UI Protect Maintainers <ui@koston.org>"]
6
6
  license = "MIT"
@@ -55,17 +55,12 @@ if TYPE_CHECKING:
55
55
  from ..data.nvr import Event
56
56
  from ..data.user import User
57
57
 
58
- try:
59
- from pydantic.v1.typing import DictStrAny
60
- except ImportError:
61
- from pydantic.typing import ( # type: ignore[assignment, no-redef]
62
- DictStrAny,
63
- )
64
-
65
58
 
66
59
  ProtectObject = TypeVar("ProtectObject", bound="ProtectBaseObject")
67
60
  RECENT_EVENT_MAX = timedelta(seconds=30)
68
61
  EVENT_PING_INTERVAL = timedelta(seconds=3)
62
+ EVENT_PING_INTERVAL_SECONDS = EVENT_PING_INTERVAL.total_seconds()
63
+
69
64
  _LOGGER = logging.getLogger(__name__)
70
65
 
71
66
 
@@ -89,7 +84,6 @@ class ProtectBaseObject(BaseModel):
89
84
  _protect_objs: ClassVar[dict[str, type[ProtectBaseObject]] | None] = None
90
85
  _protect_lists: ClassVar[dict[str, type[ProtectBaseObject]] | None] = None
91
86
  _protect_dicts: ClassVar[dict[str, type[ProtectBaseObject]] | None] = None
92
- _to_unifi_remaps: ClassVar[DictStrAny | None] = None
93
87
 
94
88
  class Config:
95
89
  arbitrary_types_allowed = True
@@ -195,6 +189,7 @@ class ProtectBaseObject(BaseModel):
195
189
  return set(self._get_unifi_remaps())
196
190
 
197
191
  @classmethod
192
+ @cache
198
193
  def _get_to_unifi_remaps(cls) -> dict[str, str]:
199
194
  """
200
195
  Helper method for overriding in child classes for reversing remap UFP
@@ -206,12 +201,9 @@ class ProtectBaseObject(BaseModel):
206
201
  "python_name": "ufpJsonName"
207
202
  }
208
203
  """
209
- if cls._to_unifi_remaps is None:
210
- cls._to_unifi_remaps = {
211
- to_key: from_key for from_key, to_key in cls._get_unifi_remaps().items()
212
- }
213
-
214
- return cls._to_unifi_remaps
204
+ return {
205
+ to_key: from_key for from_key, to_key in cls._get_unifi_remaps().items()
206
+ }
215
207
 
216
208
  @classmethod
217
209
  def _set_protect_subtypes(cls) -> None:
@@ -628,6 +620,7 @@ class ProtectModelWithId(ProtectModel):
628
620
  return obj
629
621
 
630
622
  @classmethod
623
+ @cache
631
624
  def _get_read_only_fields(cls) -> set[str]:
632
625
  return set()
633
626
 
@@ -787,10 +780,14 @@ class ProtectModelWithId(ProtectModel):
787
780
  raise
788
781
 
789
782
  if force_emit:
790
- await self.emit_message(updated)
783
+ self._emit_message(updated)
791
784
 
792
785
  async def emit_message(self, updated: dict[str, Any]) -> None:
793
- """Emites fake WS message for ProtectApiClient to process."""
786
+ """Emits fake WS message for ProtectApiClient to process."""
787
+ self._emit_message(updated)
788
+
789
+ def _emit_message(self, updated: dict[str, Any]) -> None:
790
+ """Emits fake WS message for ProtectApiClient to process."""
794
791
  if updated == {}:
795
792
  _LOGGER.debug("Event ping callback started for %s", self.id)
796
793
 
@@ -877,9 +874,9 @@ class ProtectDeviceModel(ProtectModelWithId):
877
874
  _LOGGER.debug("Event ping timer started for %s", self.id)
878
875
  loop = asyncio.get_event_loop()
879
876
  self._callback_ping = loop.call_later(
880
- EVENT_PING_INTERVAL.total_seconds(),
881
- asyncio.create_task,
882
- self.emit_message({}),
877
+ EVENT_PING_INTERVAL_SECONDS,
878
+ self._emit_message,
879
+ {},
883
880
  )
884
881
 
885
882
  async def set_name(self, name: str | None) -> None:
@@ -154,10 +154,6 @@ class ProtectDeviceRef(ProtectBaseObject):
154
154
  id: str
155
155
 
156
156
 
157
- _ModelType_NVR_value = ModelType.NVR.value
158
- _ModelType_Event_value = ModelType.EVENT.value
159
-
160
-
161
157
  class Bootstrap(ProtectBaseObject):
162
158
  auth_user_id: str
163
159
  access_key: str
@@ -360,14 +356,13 @@ class Bootstrap(ProtectBaseObject):
360
356
  elif model_type in ModelType.bootstrap_models_types_set():
361
357
  if TYPE_CHECKING:
362
358
  assert isinstance(obj, ProtectAdoptableDeviceModel)
363
- assert isinstance(obj.model, ModelType)
364
- key = obj.model.devices_key
365
359
  if not self._api.ignore_unadopted or (
366
360
  obj.is_adopted and not obj.is_adopted_by_other
367
361
  ):
368
- getattr(self, key)[obj.id] = obj
369
- ref = ProtectDeviceRef(model=obj.model, id=obj.id)
370
- self.id_lookup[obj.id] = ref
362
+ id_ = obj.id
363
+ getattr(self, model_type.devices_key)[id_] = obj
364
+ ref = ProtectDeviceRef(model=model_type, id=id_)
365
+ self.id_lookup[id_] = ref
371
366
  self.mac_lookup[normalize_mac(obj.mac)] = ref
372
367
  else:
373
368
  _LOGGER.debug("Unexpected bootstrap model type for add: %s", model_type)
File without changes
File without changes