uiprotect 2.3.0__tar.gz → 3.0.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-2.3.0 → uiprotect-3.0.0}/PKG-INFO +1 -1
  2. {uiprotect-2.3.0 → uiprotect-3.0.0}/pyproject.toml +1 -1
  3. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/api.py +13 -27
  4. {uiprotect-2.3.0 → uiprotect-3.0.0}/LICENSE +0 -0
  5. {uiprotect-2.3.0 → uiprotect-3.0.0}/README.md +0 -0
  6. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/__init__.py +0 -0
  7. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/__main__.py +0 -0
  8. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/cli/__init__.py +0 -0
  9. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/cli/backup.py +0 -0
  10. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/cli/base.py +0 -0
  11. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/cli/cameras.py +0 -0
  12. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/cli/chimes.py +0 -0
  13. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/cli/doorlocks.py +0 -0
  14. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/cli/events.py +0 -0
  15. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/cli/lights.py +0 -0
  16. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/cli/liveviews.py +0 -0
  17. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/cli/nvr.py +0 -0
  18. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/cli/sensors.py +0 -0
  19. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/cli/viewers.py +0 -0
  20. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/data/__init__.py +0 -0
  21. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/data/base.py +0 -0
  22. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/data/bootstrap.py +0 -0
  23. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/data/convert.py +0 -0
  24. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/data/devices.py +0 -0
  25. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/data/nvr.py +0 -0
  26. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/data/types.py +0 -0
  27. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/data/user.py +0 -0
  28. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/data/websocket.py +0 -0
  29. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/exceptions.py +0 -0
  30. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/py.typed +0 -0
  31. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/release_cache.json +0 -0
  32. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/stream.py +0 -0
  33. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/test_util/__init__.py +0 -0
  34. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/test_util/anonymize.py +0 -0
  35. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/utils.py +0 -0
  36. {uiprotect-2.3.0 → uiprotect-3.0.0}/src/uiprotect/websocket.py +0 -0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: uiprotect
3
- Version: 2.3.0
3
+ Version: 3.0.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 = "2.3.0"
3
+ version = "3.0.0"
4
4
  description = "Python API for Unifi Protect (Unofficial)"
5
5
  authors = ["UI Protect Maintainers <ui@koston.org>"]
6
6
  license = "MIT"
@@ -75,7 +75,6 @@ if sys.version_info[:2] < (3, 13):
75
75
 
76
76
  TOKEN_COOKIE_MAX_EXP_SECONDS = 60
77
77
 
78
- NEVER_RAN = -1000
79
78
  # how many seconds before the bootstrap is refreshed from Protect
80
79
  DEVICE_UPDATE_INTERVAL = 900
81
80
  # retry timeout for thumbnails/heatmaps
@@ -164,7 +163,6 @@ class BaseApiClient:
164
163
  _ws_timeout: int
165
164
 
166
165
  _is_authenticated: bool = False
167
- _last_update: float = NEVER_RAN
168
166
  _last_ws_status: bool = False
169
167
  _last_token_cookie: Morsel[str] | None = None
170
168
  _last_token_cookie_decode: dict[str, Any] | None = None
@@ -289,7 +287,7 @@ class BaseApiClient:
289
287
  # since the lastUpdateId is not valid anymore
290
288
  if self._update_task and not self._update_task.done():
291
289
  return
292
- self._update_task = asyncio.create_task(self.update(force=True))
290
+ self._update_task = asyncio.create_task(self.update())
293
291
 
294
292
  async def close_session(self) -> None:
295
293
  """Closing and deletes client session"""
@@ -699,7 +697,7 @@ class BaseApiClient:
699
697
  def _get_last_update_id(self) -> str | None:
700
698
  raise NotImplementedError
701
699
 
702
- async def update(self, force: bool = False) -> Bootstrap | None:
700
+ async def update(self) -> Bootstrap:
703
701
  raise NotImplementedError
704
702
 
705
703
 
@@ -710,8 +708,7 @@ class ProtectApiClient(BaseApiClient):
710
708
  UniFi Protect is a full async application. "normal" use of interacting with it is
711
709
  to call `.update()` which will initialize the `.bootstrap` and create a Websocket
712
710
  connection to UFP. This Websocket connection will emit messages that will automatically
713
- update the `.bootstrap` over time. Caling `.udpate` again (without `force`) will
714
- verify the integry of the Websocket connection.
711
+ update the `.bootstrap` over time.
715
712
 
716
713
  You can use the `.get_` methods to one off pull devices from the UFP API, but should
717
714
  not be used for building an aplication on top of.
@@ -816,32 +813,21 @@ class ProtectApiClient(BaseApiClient):
816
813
 
817
814
  return self._connection_host
818
815
 
819
- async def update(self, force: bool = False) -> Bootstrap | None:
816
+ async def update(self) -> Bootstrap:
820
817
  """
821
- Updates the state of devices, initalizes `.bootstrap` and
822
- connects to UFP Websocket for real time updates
818
+ Updates the state of devices, initializes `.bootstrap`
819
+
820
+ The websocket is auto connected once there are any
821
+ subscriptions to it. update must be called at least
822
+ once before subscribing to the websocket.
823
823
 
824
824
  You can use the various other `get_` methods if you need one off data from UFP
825
825
  """
826
826
  async with self._update_lock:
827
- now = time.monotonic()
828
- if force:
829
- self._last_update = NEVER_RAN
830
-
831
- bootstrap_updated = False
832
- if (
833
- self._bootstrap is None
834
- or now - self._last_update > DEVICE_UPDATE_INTERVAL
835
- ):
836
- bootstrap_updated = True
837
- self._bootstrap = await self.get_bootstrap()
838
- self.__dict__.pop("bootstrap", None)
839
- self._last_update = now
840
-
841
- if bootstrap_updated:
842
- return None
843
- self._last_update = now
844
- return self._bootstrap
827
+ bootstrap = await self.get_bootstrap()
828
+ self.__dict__.pop("bootstrap", None)
829
+ self._bootstrap = bootstrap
830
+ return bootstrap
845
831
 
846
832
  async def poll_events(self) -> None:
847
833
  """Poll for events."""
File without changes
File without changes