uiprotect 0.5.0__py3-none-any.whl → 0.7.0__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 uiprotect might be problematic. Click here for more details.

uiprotect/__init__.py CHANGED
@@ -2,8 +2,8 @@
2
2
 
3
3
  from __future__ import annotations
4
4
 
5
- from uiprotect.api import ProtectApiClient
6
- from uiprotect.exceptions import Invalid, NotAuthorized, NvrError
5
+ from .api import ProtectApiClient
6
+ from .exceptions import Invalid, NotAuthorized, NvrError
7
7
 
8
8
  __all__ = [
9
9
  "Invalid",
uiprotect/__main__.py CHANGED
@@ -7,7 +7,7 @@ try:
7
7
  except ImportError:
8
8
  load_dotenv = None # type: ignore[assignment]
9
9
 
10
- from uiprotect.cli import app
10
+ from .cli import app
11
11
 
12
12
 
13
13
  def start() -> None:
uiprotect/api.py CHANGED
@@ -25,7 +25,7 @@ from aiohttp import CookieJar, client_exceptions
25
25
  from platformdirs import user_cache_dir, user_config_dir
26
26
  from yarl import URL
27
27
 
28
- from uiprotect.data import (
28
+ from .data import (
29
29
  NVR,
30
30
  Bootstrap,
31
31
  Bridge,
@@ -50,11 +50,11 @@ from uiprotect.data import (
50
50
  WSSubscriptionMessage,
51
51
  create_from_unifi_dict,
52
52
  )
53
- from uiprotect.data.base import ProtectModelWithId
54
- from uiprotect.data.devices import Chime
55
- from uiprotect.data.types import IteratorCallback, ProgressCallback, RecordingMode
56
- from uiprotect.exceptions import BadRequest, NotAuthorized, NvrError
57
- from uiprotect.utils import (
53
+ from .data.base import ProtectModelWithId
54
+ from .data.devices import Chime
55
+ from .data.types import IteratorCallback, ProgressCallback, RecordingMode
56
+ from .exceptions import BadRequest, NotAuthorized, NvrError
57
+ from .utils import (
58
58
  decode_token_cookie,
59
59
  get_response_reason,
60
60
  ip_from_host,
@@ -62,7 +62,7 @@ from uiprotect.utils import (
62
62
  to_js_time,
63
63
  utc_now,
64
64
  )
65
- from uiprotect.websocket import Websocket
65
+ from .websocket import Websocket
66
66
 
67
67
  TOKEN_COOKIE_MAX_EXP_SECONDS = 60
68
68
 
uiprotect/cli/__init__.py CHANGED
@@ -12,23 +12,24 @@ import typer
12
12
  from rich.progress import track
13
13
 
14
14
  from uiprotect.api import ProtectApiClient
15
- from uiprotect.cli.base import CliContext, OutputFormatEnum
16
- from uiprotect.cli.cameras import app as camera_app
17
- from uiprotect.cli.chimes import app as chime_app
18
- from uiprotect.cli.doorlocks import app as doorlock_app
19
- from uiprotect.cli.events import app as event_app
20
- from uiprotect.cli.lights import app as light_app
21
- from uiprotect.cli.liveviews import app as liveview_app
22
- from uiprotect.cli.nvr import app as nvr_app
23
- from uiprotect.cli.sensors import app as sensor_app
24
- from uiprotect.cli.viewers import app as viewer_app
25
- from uiprotect.data import Version, WSPacket
26
- from uiprotect.test_util import SampleDataGenerator
27
- from uiprotect.utils import RELEASE_CACHE, get_local_timezone, run_async
28
- from uiprotect.utils import profile_ws as profile_ws_job
15
+
16
+ from ..data import Version, WSPacket
17
+ from ..test_util import SampleDataGenerator
18
+ from ..utils import RELEASE_CACHE, get_local_timezone, run_async
19
+ from ..utils import profile_ws as profile_ws_job
20
+ from .base import CliContext, OutputFormatEnum
21
+ from .cameras import app as camera_app
22
+ from .chimes import app as chime_app
23
+ from .doorlocks import app as doorlock_app
24
+ from .events import app as event_app
25
+ from .lights import app as light_app
26
+ from .liveviews import app as liveview_app
27
+ from .nvr import app as nvr_app
28
+ from .sensors import app as sensor_app
29
+ from .viewers import app as viewer_app
29
30
 
30
31
  try:
31
- from uiprotect.cli.backup import app as backup_app
32
+ from .backup import app as backup_app
32
33
  except ImportError:
33
34
  backup_app = None # type: ignore[assignment]
34
35
 
uiprotect/cli/backup.py CHANGED
@@ -32,10 +32,10 @@ from sqlalchemy import event as saevent
32
32
  from sqlalchemy.ext.asyncio import AsyncEngine, AsyncSession, create_async_engine
33
33
  from sqlalchemy.orm import Mapped, declarative_base, relationship
34
34
 
35
- from uiprotect import data as d
36
- from uiprotect.api import ProtectApiClient
37
- from uiprotect.cli import base
38
- from uiprotect.utils import (
35
+ from .. import data as d
36
+ from ..api import ProtectApiClient
37
+ from ..cli import base
38
+ from ..utils import (
39
39
  format_duration,
40
40
  get_local_timezone,
41
41
  local_datetime,
uiprotect/cli/base.py CHANGED
@@ -9,10 +9,10 @@ import orjson
9
9
  import typer
10
10
  from pydantic.v1 import ValidationError
11
11
 
12
- from uiprotect.api import ProtectApiClient
13
- from uiprotect.data import NVR, ProtectAdoptableDeviceModel, ProtectBaseObject
14
- from uiprotect.exceptions import BadRequest, NvrError, StreamError
15
- from uiprotect.utils import run_async
12
+ from ..api import ProtectApiClient
13
+ from ..data import NVR, ProtectAdoptableDeviceModel, ProtectBaseObject
14
+ from ..exceptions import BadRequest, NvrError, StreamError
15
+ from ..utils import run_async
16
16
 
17
17
  try:
18
18
  from pydantic.v1 import ValidationError
uiprotect/cli/cameras.py CHANGED
@@ -8,9 +8,9 @@ from typing import Optional, cast
8
8
  import typer
9
9
  from rich.progress import Progress
10
10
 
11
- from uiprotect import data as d
12
- from uiprotect.api import ProtectApiClient
13
- from uiprotect.cli import base
11
+ from .. import data as d
12
+ from ..api import ProtectApiClient
13
+ from ..cli import base
14
14
 
15
15
  app = typer.Typer(rich_markup_mode="rich")
16
16
 
uiprotect/cli/chimes.py CHANGED
@@ -5,9 +5,9 @@ from typing import Optional
5
5
 
6
6
  import typer
7
7
 
8
- from uiprotect.api import ProtectApiClient
9
- from uiprotect.cli import base
10
- from uiprotect.data import Chime
8
+ from ..api import ProtectApiClient
9
+ from ..cli import base
10
+ from ..data import Chime
11
11
 
12
12
  app = typer.Typer(rich_markup_mode="rich")
13
13
 
@@ -6,9 +6,9 @@ from typing import Optional
6
6
 
7
7
  import typer
8
8
 
9
- from uiprotect.api import ProtectApiClient
10
- from uiprotect.cli import base
11
- from uiprotect.data import Doorlock
9
+ from ..api import ProtectApiClient
10
+ from ..cli import base
11
+ from ..data import Doorlock
12
12
 
13
13
  app = typer.Typer(rich_markup_mode="rich")
14
14
 
uiprotect/cli/events.py CHANGED
@@ -9,11 +9,11 @@ from typing import Optional
9
9
  import typer
10
10
  from rich.progress import Progress
11
11
 
12
- from uiprotect import data as d
13
- from uiprotect.api import ProtectApiClient
14
- from uiprotect.cli import base
15
- from uiprotect.exceptions import NvrError
16
- from uiprotect.utils import local_datetime
12
+ from .. import data as d
13
+ from ..api import ProtectApiClient
14
+ from ..cli import base
15
+ from ..exceptions import NvrError
16
+ from ..utils import local_datetime
17
17
 
18
18
  app = typer.Typer(rich_markup_mode="rich")
19
19
 
uiprotect/cli/lights.py CHANGED
@@ -6,9 +6,9 @@ from typing import Optional
6
6
 
7
7
  import typer
8
8
 
9
- from uiprotect.api import ProtectApiClient
10
- from uiprotect.cli import base
11
- from uiprotect.data import Light
9
+ from ..api import ProtectApiClient
10
+ from ..cli import base
11
+ from ..data import Light
12
12
 
13
13
  app = typer.Typer(rich_markup_mode="rich")
14
14
 
@@ -5,9 +5,9 @@ from typing import Optional
5
5
 
6
6
  import typer
7
7
 
8
- from uiprotect.api import ProtectApiClient
9
- from uiprotect.cli import base
10
- from uiprotect.data import Liveview
8
+ from ..api import ProtectApiClient
9
+ from ..cli import base
10
+ from ..data import Liveview
11
11
 
12
12
  app = typer.Typer(rich_markup_mode="rich")
13
13
 
uiprotect/cli/nvr.py CHANGED
@@ -6,8 +6,8 @@ from datetime import timedelta
6
6
  import orjson
7
7
  import typer
8
8
 
9
- from uiprotect.cli import base
10
- from uiprotect.data import NVR, AnalyticsOption
9
+ from ..cli import base
10
+ from ..data import NVR, AnalyticsOption
11
11
 
12
12
  app = typer.Typer(rich_markup_mode="rich")
13
13
 
uiprotect/cli/sensors.py CHANGED
@@ -5,9 +5,9 @@ from typing import Optional
5
5
 
6
6
  import typer
7
7
 
8
- from uiprotect.api import ProtectApiClient
9
- from uiprotect.cli import base
10
- from uiprotect.data import MountType, Sensor
8
+ from ..api import ProtectApiClient
9
+ from ..cli import base
10
+ from ..data import MountType, Sensor
11
11
 
12
12
  app = typer.Typer(rich_markup_mode="rich")
13
13
 
uiprotect/cli/viewers.py CHANGED
@@ -5,9 +5,9 @@ from typing import Optional
5
5
 
6
6
  import typer
7
7
 
8
- from uiprotect.api import ProtectApiClient
9
- from uiprotect.cli import base
10
- from uiprotect.data import Viewer
8
+ from ..api import ProtectApiClient
9
+ from ..cli import base
10
+ from ..data import Viewer
11
11
 
12
12
  app = typer.Typer(rich_markup_mode="rich")
13
13
 
@@ -1,15 +1,15 @@
1
1
  from __future__ import annotations
2
2
 
3
- from uiprotect.data.base import (
3
+ from .base import (
4
4
  ProtectAdoptableDeviceModel,
5
5
  ProtectBaseObject,
6
6
  ProtectDeviceModel,
7
7
  ProtectModel,
8
8
  ProtectModelWithId,
9
9
  )
10
- from uiprotect.data.bootstrap import Bootstrap
11
- from uiprotect.data.convert import create_from_unifi_dict
12
- from uiprotect.data.devices import (
10
+ from .bootstrap import Bootstrap
11
+ from .convert import create_from_unifi_dict
12
+ from .devices import (
13
13
  Bridge,
14
14
  Camera,
15
15
  CameraChannel,
@@ -21,7 +21,7 @@ from uiprotect.data.devices import (
21
21
  Sensor,
22
22
  Viewer,
23
23
  )
24
- from uiprotect.data.nvr import (
24
+ from .nvr import (
25
25
  NVR,
26
26
  DoorbellMessage,
27
27
  Event,
@@ -30,7 +30,7 @@ from uiprotect.data.nvr import (
30
30
  SmartDetectItem,
31
31
  SmartDetectTrack,
32
32
  )
33
- from uiprotect.data.types import (
33
+ from .types import (
34
34
  DEFAULT,
35
35
  DEFAULT_TYPE,
36
36
  AnalyticsOption,
@@ -69,8 +69,8 @@ from uiprotect.data.types import (
69
69
  VideoMode,
70
70
  WDRLevel,
71
71
  )
72
- from uiprotect.data.user import CloudAccount, Group, Permission, User, UserLocation
73
- from uiprotect.data.websocket import (
72
+ from .user import CloudAccount, Group, Permission, User, UserLocation
73
+ from .websocket import (
74
74
  WS_HEADER_SIZE,
75
75
  WSAction,
76
76
  WSJSONPacketFrame,
uiprotect/data/base.py CHANGED
@@ -11,28 +11,28 @@ from ipaddress import IPv4Address
11
11
  from typing import TYPE_CHECKING, Any, ClassVar, TypeVar
12
12
  from uuid import UUID
13
13
 
14
- from uiprotect.data.types import (
14
+ from ..exceptions import BadRequest, ClientError, NotAuthorized
15
+ from ..utils import (
16
+ asyncio_timeout,
17
+ convert_unifi_data,
18
+ dict_diff,
19
+ is_debug,
20
+ process_datetime,
21
+ serialize_unifi_obj,
22
+ to_snake_case,
23
+ )
24
+ from .types import (
15
25
  ModelType,
16
26
  PercentFloat,
17
27
  PermissionNode,
18
28
  ProtectWSPayloadFormat,
19
29
  StateType,
20
30
  )
21
- from uiprotect.data.websocket import (
31
+ from .websocket import (
22
32
  WSJSONPacketFrame,
23
33
  WSPacket,
24
34
  WSPacketFrameHeader,
25
35
  )
26
- from uiprotect.exceptions import BadRequest, ClientError, NotAuthorized
27
- from uiprotect.utils import (
28
- asyncio_timeout,
29
- convert_unifi_data,
30
- dict_diff,
31
- is_debug,
32
- process_datetime,
33
- serialize_unifi_obj,
34
- to_snake_case,
35
- )
36
36
 
37
37
  try:
38
38
  from pydantic.v1 import BaseModel
@@ -50,17 +50,16 @@ if TYPE_CHECKING:
50
50
 
51
51
  from typing_extensions import Self # requires Python 3.11+
52
52
 
53
- from uiprotect.api import ProtectApiClient
54
- from uiprotect.data.devices import Bridge
55
- from uiprotect.data.nvr import Event
56
- from uiprotect.data.user import User
53
+ from ..api import ProtectApiClient
54
+ from ..data.devices import Bridge
55
+ from ..data.nvr import Event
56
+ from ..data.user import User
57
57
 
58
58
  try:
59
- from pydantic.v1.typing import DictStrAny, SetStr
59
+ from pydantic.v1.typing import DictStrAny
60
60
  except ImportError:
61
61
  from pydantic.typing import ( # type: ignore[assignment, no-redef]
62
62
  DictStrAny,
63
- SetStr,
64
63
  )
65
64
 
66
65
 
@@ -88,11 +87,8 @@ class ProtectBaseObject(BaseModel):
88
87
  _api: ProtectApiClient | None = PrivateAttr(None)
89
88
 
90
89
  _protect_objs: ClassVar[dict[str, type[ProtectBaseObject]] | None] = None
91
- _protect_objs_set: ClassVar[SetStr | None] = None
92
90
  _protect_lists: ClassVar[dict[str, type[ProtectBaseObject]] | None] = None
93
- _protect_lists_set: ClassVar[SetStr | None] = None
94
91
  _protect_dicts: ClassVar[dict[str, type[ProtectBaseObject]] | None] = None
95
- _protect_dicts_set: ClassVar[SetStr | None] = None
96
92
  _to_unifi_remaps: ClassVar[DictStrAny | None] = None
97
93
 
98
94
  class Config:
@@ -140,7 +136,7 @@ class ProtectBaseObject(BaseModel):
140
136
 
141
137
  @classmethod
142
138
  def construct(cls, _fields_set: set[str] | None = None, **values: Any) -> Self:
143
- api = values.pop("api", None)
139
+ api: ProtectApiClient | None = values.pop("api", None)
144
140
  values_set = set(values)
145
141
 
146
142
  unifi_objs = cls._get_protect_objs()
@@ -192,6 +188,12 @@ class ProtectBaseObject(BaseModel):
192
188
  """
193
189
  return {}
194
190
 
191
+ @classmethod
192
+ @cache
193
+ def _get_unifi_remaps_set(self) -> set[str]:
194
+ """Helper method to get set of all child UFP objects."""
195
+ return set(self._get_unifi_remaps())
196
+
195
197
  @classmethod
196
198
  def _get_to_unifi_remaps(cls) -> dict[str, str]:
197
199
  """
@@ -231,63 +233,49 @@ class ProtectBaseObject(BaseModel):
231
233
  pass
232
234
 
233
235
  @classmethod
236
+ @cache
234
237
  def _get_protect_objs(cls) -> dict[str, type[ProtectBaseObject]]:
235
238
  """Helper method to get all child UFP objects"""
236
- if cls._protect_objs is not None:
237
- return cls._protect_objs
238
-
239
- cls._set_protect_subtypes()
240
- return cls._protect_objs # type: ignore[return-value]
239
+ if cls._protect_objs is None:
240
+ cls._set_protect_subtypes()
241
+ assert cls._protect_objs is not None
242
+ return cls._protect_objs
241
243
 
242
244
  @classmethod
245
+ @cache
243
246
  def _get_protect_objs_set(cls) -> set[str]:
244
247
  """Helper method to get all child UFP objects"""
245
- if cls._protect_objs_set is None:
246
- cls._protect_objs_set = set(cls._get_protect_objs().keys())
247
-
248
- return cls._protect_objs_set
248
+ return set(cls._get_protect_objs())
249
249
 
250
250
  @classmethod
251
+ @cache
251
252
  def _get_protect_lists(cls) -> dict[str, type[ProtectBaseObject]]:
252
253
  """Helper method to get all child of UFP objects (lists)"""
253
- if cls._protect_lists is not None:
254
- return cls._protect_lists
255
-
256
- cls._set_protect_subtypes()
257
- return cls._protect_lists # type: ignore[return-value]
254
+ if cls._protect_lists is None:
255
+ cls._set_protect_subtypes()
256
+ assert cls._protect_lists is not None
257
+ return cls._protect_lists
258
258
 
259
259
  @classmethod
260
+ @cache
260
261
  def _get_protect_lists_set(cls) -> set[str]:
261
262
  """Helper method to get all child UFP objects"""
262
- if cls._protect_lists_set is None:
263
- cls._protect_lists_set = set(cls._get_protect_lists().keys())
264
-
265
- return cls._protect_lists_set
263
+ return set(cls._get_protect_lists())
266
264
 
267
265
  @classmethod
266
+ @cache
268
267
  def _get_protect_dicts(cls) -> dict[str, type[ProtectBaseObject]]:
269
268
  """Helper method to get all child of UFP objects (dicts)"""
270
- if cls._protect_dicts is not None:
271
- return cls._protect_dicts
272
-
273
- cls._set_protect_subtypes()
274
- return cls._protect_dicts # type: ignore[return-value]
269
+ if cls._protect_dicts is None:
270
+ cls._set_protect_subtypes()
271
+ assert cls._protect_dicts is not None
272
+ return cls._protect_dicts
275
273
 
276
274
  @classmethod
275
+ @cache
277
276
  def _get_protect_dicts_set(cls) -> set[str]:
278
277
  """Helper method to get all child UFP objects"""
279
- if cls._protect_dicts_set is None:
280
- cls._protect_dicts_set = set(cls._get_protect_dicts().keys())
281
-
282
- return cls._protect_dicts_set
283
-
284
- @classmethod
285
- def _get_api(cls, api: ProtectApiClient | None) -> ProtectApiClient | None:
286
- """Helper method to try to find and the current ProjtectAPIClient instance from given data"""
287
- if api is None and isinstance(cls, ProtectBaseObject) and hasattr(cls, "_api"): # type: ignore[unreachable]
288
- api = cls._api # type: ignore[unreachable]
289
-
290
- return api
278
+ return set(cls._get_protect_dicts())
291
279
 
292
280
  @classmethod
293
281
  def _clean_protect_obj(
@@ -340,11 +328,13 @@ class ProtectBaseObject(BaseModel):
340
328
 
341
329
  """
342
330
  # get the API client instance
343
- api = cls._get_api(data.get("api"))
331
+ api: ProtectApiClient | None = data.get("api") or (
332
+ cls._api if isinstance(cls, ProtectBaseObject) else None
333
+ )
344
334
 
345
335
  # remap keys that will not be converted correctly by snake_case convert
346
336
  remaps = cls._get_unifi_remaps()
347
- for from_key in set(remaps).intersection(data):
337
+ for from_key in cls._get_unifi_remaps_set().intersection(data):
348
338
  data[remaps[from_key]] = data.pop(from_key)
349
339
 
350
340
  # convert to snake_case and remove extra fields
@@ -7,7 +7,7 @@ import logging
7
7
  from copy import deepcopy
8
8
  from dataclasses import dataclass
9
9
  from datetime import datetime
10
- from typing import Any, cast
10
+ from typing import TYPE_CHECKING, Any, cast
11
11
 
12
12
  from aiohttp.client_exceptions import ServerDisconnectedError
13
13
 
@@ -16,14 +16,16 @@ try:
16
16
  except ImportError:
17
17
  from pydantic import PrivateAttr, ValidationError # type: ignore[assignment]
18
18
 
19
- from uiprotect.data.base import (
19
+ from ..exceptions import ClientError
20
+ from ..utils import utc_now
21
+ from .base import (
20
22
  RECENT_EVENT_MAX,
21
23
  ProtectBaseObject,
22
24
  ProtectModel,
23
25
  ProtectModelWithId,
24
26
  )
25
- from uiprotect.data.convert import create_from_unifi_dict
26
- from uiprotect.data.devices import (
27
+ from .convert import create_from_unifi_dict
28
+ from .devices import (
27
29
  Bridge,
28
30
  Camera,
29
31
  Chime,
@@ -33,17 +35,19 @@ from uiprotect.data.devices import (
33
35
  Sensor,
34
36
  Viewer,
35
37
  )
36
- from uiprotect.data.nvr import NVR, Event, Liveview
37
- from uiprotect.data.types import EventType, FixSizeOrderedDict, ModelType
38
- from uiprotect.data.user import Group, User
39
- from uiprotect.data.websocket import (
38
+ from .nvr import NVR, Event, Liveview
39
+ from .types import EventType, FixSizeOrderedDict, ModelType
40
+ from .user import Group, User
41
+ from .websocket import (
40
42
  WSAction,
41
43
  WSJSONPacketFrame,
42
44
  WSPacket,
43
45
  WSSubscriptionMessage,
44
46
  )
45
- from uiprotect.exceptions import ClientError
46
- from uiprotect.utils import utc_now
47
+
48
+ if TYPE_CHECKING:
49
+ from ..api import ProtectApiClient
50
+
47
51
 
48
52
  _LOGGER = logging.getLogger(__name__)
49
53
 
@@ -198,7 +202,9 @@ class Bootstrap(ProtectBaseObject):
198
202
 
199
203
  @classmethod
200
204
  def unifi_dict_to_dict(cls, data: dict[str, Any]) -> dict[str, Any]:
201
- api = cls._get_api(data.get("api"))
205
+ api: ProtectApiClient | None = data.get("api") or (
206
+ cls._api if isinstance(cls, ProtectBaseObject) else None
207
+ )
202
208
  data["macLookup"] = {}
203
209
  data["idLookup"] = {}
204
210
  for model_type in ModelType.bootstrap_models():
uiprotect/data/convert.py CHANGED
@@ -4,7 +4,8 @@ from __future__ import annotations
4
4
 
5
5
  from typing import TYPE_CHECKING, Any
6
6
 
7
- from uiprotect.data.devices import (
7
+ from ..exceptions import DataDecodeError
8
+ from .devices import (
8
9
  Bridge,
9
10
  Camera,
10
11
  Chime,
@@ -13,14 +14,13 @@ from uiprotect.data.devices import (
13
14
  Sensor,
14
15
  Viewer,
15
16
  )
16
- from uiprotect.data.nvr import NVR, Event, Liveview
17
- from uiprotect.data.types import ModelType
18
- from uiprotect.data.user import CloudAccount, Group, User, UserLocation
19
- from uiprotect.exceptions import DataDecodeError
17
+ from .nvr import NVR, Event, Liveview
18
+ from .types import ModelType
19
+ from .user import CloudAccount, Group, User, UserLocation
20
20
 
21
21
  if TYPE_CHECKING:
22
- from uiprotect.api import ProtectApiClient
23
- from uiprotect.data.base import ProtectModel
22
+ from ..api import ProtectApiClient
23
+ from ..data.base import ProtectModel
24
24
 
25
25
 
26
26
  MODEL_TO_CLASS: dict[str, type[ProtectModel]] = {
uiprotect/data/devices.py CHANGED
@@ -17,13 +17,26 @@ try:
17
17
  except ImportError:
18
18
  from pydantic.fields import PrivateAttr
19
19
 
20
- from uiprotect.data.base import (
20
+ from ..exceptions import BadRequest, NotAuthorized, StreamError
21
+ from ..stream import TalkbackStream
22
+ from ..utils import (
23
+ clamp_value,
24
+ convert_smart_audio_types,
25
+ convert_smart_types,
26
+ convert_video_modes,
27
+ from_js_time,
28
+ process_datetime,
29
+ serialize_point,
30
+ to_js_time,
31
+ utc_now,
32
+ )
33
+ from .base import (
21
34
  EVENT_PING_INTERVAL,
22
35
  ProtectAdoptableDeviceModel,
23
36
  ProtectBaseObject,
24
37
  ProtectMotionDeviceModel,
25
38
  )
26
- from uiprotect.data.types import (
39
+ from .types import (
27
40
  DEFAULT,
28
41
  DEFAULT_TYPE,
29
42
  AudioCodecs,
@@ -65,23 +78,10 @@ from uiprotect.data.types import (
65
78
  VideoMode,
66
79
  WDRLevel,
67
80
  )
68
- from uiprotect.data.user import User
69
- from uiprotect.exceptions import BadRequest, NotAuthorized, StreamError
70
- from uiprotect.stream import TalkbackStream
71
- from uiprotect.utils import (
72
- clamp_value,
73
- convert_smart_audio_types,
74
- convert_smart_types,
75
- convert_video_modes,
76
- from_js_time,
77
- process_datetime,
78
- serialize_point,
79
- to_js_time,
80
- utc_now,
81
- )
81
+ from .user import User
82
82
 
83
83
  if TYPE_CHECKING:
84
- from uiprotect.data.nvr import Event, Liveview
84
+ from .nvr import Event, Liveview
85
85
 
86
86
  PRIVACY_ZONE_NAME = "pyufp_privacy_zone"
87
87
  LUX_MAPPING_VALUES = [
uiprotect/data/nvr.py CHANGED
@@ -16,12 +16,14 @@ import aiofiles
16
16
  import orjson
17
17
  from aiofiles import os as aos
18
18
 
19
- from uiprotect.data.base import (
19
+ from ..exceptions import BadRequest, NotAuthorized
20
+ from ..utils import RELEASE_CACHE, process_datetime
21
+ from .base import (
20
22
  ProtectBaseObject,
21
23
  ProtectDeviceModel,
22
24
  ProtectModelWithId,
23
25
  )
24
- from uiprotect.data.devices import (
26
+ from .devices import (
25
27
  Camera,
26
28
  CameraZone,
27
29
  Light,
@@ -30,7 +32,7 @@ from uiprotect.data.devices import (
30
32
  Sensor,
31
33
  SmartDetectSettings,
32
34
  )
33
- from uiprotect.data.types import (
35
+ from .types import (
34
36
  AnalyticsOption,
35
37
  DoorbellMessageType,
36
38
  DoorbellText,
@@ -53,9 +55,7 @@ from uiprotect.data.types import (
53
55
  StorageType,
54
56
  Version,
55
57
  )
56
- from uiprotect.data.user import User, UserLocation
57
- from uiprotect.exceptions import BadRequest, NotAuthorized
58
- from uiprotect.utils import RELEASE_CACHE, process_datetime
58
+ from .user import User, UserLocation
59
59
 
60
60
  try:
61
61
  from pydantic.v1.fields import PrivateAttr
uiprotect/data/user.py CHANGED
@@ -11,8 +11,8 @@ try:
11
11
  except ImportError:
12
12
  from pydantic.fields import PrivateAttr
13
13
 
14
- from uiprotect.data.base import ProtectBaseObject, ProtectModel, ProtectModelWithId
15
- from uiprotect.data.types import ModelType, PermissionNode
14
+ from .base import ProtectBaseObject, ProtectModel, ProtectModelWithId
15
+ from .types import ModelType, PermissionNode
16
16
 
17
17
 
18
18
  class Permission(ProtectBaseObject):
@@ -11,11 +11,11 @@ from typing import TYPE_CHECKING, Any
11
11
 
12
12
  import orjson
13
13
 
14
- from uiprotect.data.types import ProtectWSPayloadFormat
15
- from uiprotect.exceptions import WSDecodeError, WSEncodeError
14
+ from ..exceptions import WSDecodeError, WSEncodeError
15
+ from .types import ProtectWSPayloadFormat
16
16
 
17
17
  if TYPE_CHECKING:
18
- from uiprotect.data.base import ProtectModelWithId
18
+ from .base import ProtectModelWithId
19
19
 
20
20
  WS_HEADER_SIZE = 8
21
21
 
uiprotect/stream.py CHANGED
@@ -11,10 +11,10 @@ from urllib.parse import urlparse
11
11
 
12
12
  from aioshutil import which
13
13
 
14
- from uiprotect.exceptions import BadRequest, StreamError
14
+ from .exceptions import BadRequest, StreamError
15
15
 
16
16
  if TYPE_CHECKING:
17
- from uiprotect.data import Camera
17
+ from .data import Camera
18
18
 
19
19
  _LOGGER = logging.getLogger(__name__)
20
20
 
@@ -15,14 +15,14 @@ from typing import Any, overload
15
15
  import aiohttp
16
16
  from PIL import Image
17
17
 
18
- from uiprotect.api import ProtectApiClient
19
- from uiprotect.data import EventType, WSJSONPacketFrame, WSPacket
20
- from uiprotect.exceptions import BadRequest
21
- from uiprotect.test_util.anonymize import (
18
+ from ..api import ProtectApiClient
19
+ from ..data import EventType, WSJSONPacketFrame, WSPacket
20
+ from ..exceptions import BadRequest
21
+ from ..test_util.anonymize import (
22
22
  anonymize_data,
23
23
  anonymize_prefixed_event_id,
24
24
  )
25
- from uiprotect.utils import from_js_time, is_online, run_async, write_json
25
+ from ..utils import from_js_time, is_online, run_async, write_json
26
26
 
27
27
  BLANK_VIDEO_CMD = "ffmpeg -y -hide_banner -loglevel error -f lavfi -i color=size=1280x720:rate=25:color=black -f lavfi -i anullsrc=channel_layout=stereo:sample_rate=44100 -t {length} {filename}"
28
28
 
@@ -8,7 +8,7 @@ from urllib.parse import urlparse
8
8
 
9
9
  import typer
10
10
 
11
- from uiprotect.data import ModelType
11
+ from ..data import ModelType
12
12
 
13
13
  object_id_mapping: dict[str, str] = {}
14
14
 
uiprotect/utils.py CHANGED
@@ -29,14 +29,14 @@ from uuid import UUID
29
29
  import jwt
30
30
  from aiohttp import ClientResponse
31
31
 
32
- from uiprotect.data.types import (
32
+ from .data.types import (
33
33
  Color,
34
34
  SmartDetectAudioType,
35
35
  SmartDetectObjectType,
36
36
  Version,
37
37
  VideoMode,
38
38
  )
39
- from uiprotect.exceptions import NvrError
39
+ from .exceptions import NvrError
40
40
 
41
41
  try:
42
42
  from pydantic.v1.fields import SHAPE_DICT, SHAPE_LIST, SHAPE_SET, ModelField
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.1
2
2
  Name: uiprotect
3
- Version: 0.5.0
3
+ Version: 0.7.0
4
4
  Summary: Python API for Unifi Protect (Unofficial)
5
5
  Home-page: https://github.com/uilibs/uiprotect
6
6
  License: MIT
@@ -0,0 +1,37 @@
1
+ uiprotect/__init__.py,sha256=llnQNtiBfwQG8IkQXovvFz4LZeFjrJx7XdmmUhu3a9E,289
2
+ uiprotect/__main__.py,sha256=C_bHCOkv5qj6WMy-6ELoY3Y6HDhLxOa1a30CzmbZhsg,462
3
+ uiprotect/api.py,sha256=1eIAuA4GC32-mpibk-Avd4vU59fT_UgxqjKVP9ISTkY,65943
4
+ uiprotect/cli/__init__.py,sha256=sSLW9keVQOkgFcMW18HTDjRrt9sJ0KWjn9DJDA6f9Pc,8658
5
+ uiprotect/cli/backup.py,sha256=SxUyFFwLHcU60qsI8qBS_Xw7RLJeqUEdMAyjwk30MKw,36715
6
+ uiprotect/cli/base.py,sha256=zpTm2kyJe_GLixnv3Uadke__iRLh64AEwQzp-2hqS7g,7730
7
+ uiprotect/cli/cameras.py,sha256=YvvMccQEYG3Wih0Ix8tan1R1vfaJ6cogg6YKWLzMUV8,16973
8
+ uiprotect/cli/chimes.py,sha256=XANn21bQVkestkKOm9HjxSM8ZGrRrqvUXLouaQ3LTqs,5326
9
+ uiprotect/cli/doorlocks.py,sha256=Go_Tn68bAcmrRAnUIi4kBiR7ciKQsu_R150ubPTjUAs,3523
10
+ uiprotect/cli/events.py,sha256=D5SRejKzsPpKlZ9O2J4wkJRigFRVEymiLyU8VQ43fqI,7186
11
+ uiprotect/cli/lights.py,sha256=RxP1ebYEn2o5812OfrovmJLaNuIDoSNWiX1FvCbcdDw,3314
12
+ uiprotect/cli/liveviews.py,sha256=GU5z-ZLRBXHyspDKiJpiv-kbaBcvxK_-K70rPoqx2Ms,1863
13
+ uiprotect/cli/nvr.py,sha256=TwxEg2XT8jXAbOqv6gc7KFXELKadeItEDYweSL4_-e8,4260
14
+ uiprotect/cli/sensors.py,sha256=fQtcDJCVxs4VbAqcavgBy2ABiVxAW3GXtna6_XFBp2k,8153
15
+ uiprotect/cli/viewers.py,sha256=2cyrp104ffIvgT0wYGIO0G35QMkEbFe7fSVqLwDXQYQ,2171
16
+ uiprotect/data/__init__.py,sha256=OcfuJl2qXfHcj_mdnrHhzZ5tEIZrw8auziX5IE7dn-I,2938
17
+ uiprotect/data/base.py,sha256=f032w_AnTT3Hd85eBVs2XdnyzHpckdCwiJrsMQyLsR8,37192
18
+ uiprotect/data/bootstrap.py,sha256=ibfCHqNhH44iw-JsuQs41zBCjb9ksSXz_QQq7qDbLsQ,21876
19
+ uiprotect/data/convert.py,sha256=rOQplUMIdTMD2SbAx_iI9BNPDscnhDvyRVLEMDhtADg,2047
20
+ uiprotect/data/devices.py,sha256=AsCQCoOpswdIU7X5ty1XhhOl2v6CkQCXu2Y-lIS_6_k,111712
21
+ uiprotect/data/nvr.py,sha256=c8WxXpBcMaZ5REzCUb8aqmlLkttFYO1O5jLMhus5rkw,47605
22
+ uiprotect/data/types.py,sha256=MTi9dVzKTp_8XtAmWKtbZujwE5plKGHdjglFGcJ4Yxs,15789
23
+ uiprotect/data/user.py,sha256=yBnUQ3qpHL745hLhR41WjWv_Yx51RlmfHapgvK0KSgM,7067
24
+ uiprotect/data/websocket.py,sha256=lkdobRh5SPu7YzLHyhZVe7qlh5W3L8LKzS63Md-4DOk,6048
25
+ uiprotect/exceptions.py,sha256=kgn0cRM6lTtgLza09SDa3ZiX6ue1QqHCOogQ4qu6KTQ,965
26
+ uiprotect/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
+ uiprotect/release_cache.json,sha256=NamnSFy78hOWY0DPO87J9ELFCAN6NnVquv8gQO75ZG4,386
28
+ uiprotect/stream.py,sha256=McV3XymKyjn-1uV5jdQHcpaDjqLS4zWyMASQ8ubcyb4,4924
29
+ uiprotect/test_util/__init__.py,sha256=d2g7afa0LSdixQ0kjEDYwafDFME_UlW2LzxpamZ2BC0,18556
30
+ uiprotect/test_util/anonymize.py,sha256=f-8ijU-_y9r-uAbhIPn0f0I6hzJpAkvJzc8UpWihObI,8478
31
+ uiprotect/utils.py,sha256=gCLoZBQ94Yi9PqefiqTZK7WrvT3Byue79a4jvDc0k44,18226
32
+ uiprotect/websocket.py,sha256=iMTdchymaCgVHsmY1bRbxkcymqt6WQircIHYNxCu178,7289
33
+ uiprotect-0.7.0.dist-info/LICENSE,sha256=INx18jhdbVXMEiiBANeKEbrbz57ckgzxk5uutmmcxGk,1111
34
+ uiprotect-0.7.0.dist-info/METADATA,sha256=RDKJOvu9_P8mVZTKOBwzBBfZhxXdU_KdMHbUrMQEnZ4,10984
35
+ uiprotect-0.7.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
36
+ uiprotect-0.7.0.dist-info/entry_points.txt,sha256=J78AUTPrTTxgI3s7SVgrmGqDP7piX2wuuEORzhDdVRA,47
37
+ uiprotect-0.7.0.dist-info/RECORD,,
@@ -1,37 +0,0 @@
1
- uiprotect/__init__.py,sha256=tzcxK6cOIIkFEtST4Zjq3bafYTFWtwnaL92DgypjFi8,307
2
- uiprotect/__main__.py,sha256=T69KE5W4zek6qeNEL8_Fq2DEfBc04SqSuIOJpiW4ydE,471
3
- uiprotect/api.py,sha256=G2cvwLuanzvZ7dGfJOlAMvbKSBIsb7t3uOPB-KyT8gk,66006
4
- uiprotect/cli/__init__.py,sha256=tmwtYrhM8rjOw8noKD6NALl_2Nu3xIycDuQyEKD5oMk,8832
5
- uiprotect/cli/backup.py,sha256=Mtjd2f0w7zjIeLkJILKxiBnZJYXypzC9gpyAmBZ8sq0,36746
6
- uiprotect/cli/base.py,sha256=dE6vYb4nLAYbUdHwcKkN7I3iXqTjz84jfHGnsLmk_Ds,7762
7
- uiprotect/cli/cameras.py,sha256=mVLJ5FjZPSbpNXvtd7Yiz17zMDSdLWT0p6Wcaqpt0GQ,16996
8
- uiprotect/cli/chimes.py,sha256=92kNiZN7FpuCF7CqK9oLPt2jQ96tNhTjP1JcOdJAKhU,5350
9
- uiprotect/cli/doorlocks.py,sha256=XMftrrK0O0bWZHOuTwg9m4p9U7gC0FzHFb72bSnlUEg,3547
10
- uiprotect/cli/events.py,sha256=Ni_igTOdOf11pklpNEocBdwd3EW6O0wD8Iz-lN2zMJA,7225
11
- uiprotect/cli/lights.py,sha256=EgJsQ37c3QzSKoYf6h-rCaQoiftNh2igY1bTB_tQz14,3338
12
- uiprotect/cli/liveviews.py,sha256=TrLAqG2_GpNoWyw9IRY-4mJmlFwxGZxUuIdi-YU_NuM,1887
13
- uiprotect/cli/nvr.py,sha256=PVpUitWzP9HLy2yoj0HP-b-4Te5AFCrahUAmrQJ4z-w,4276
14
- uiprotect/cli/sensors.py,sha256=CE77weDkYepo9eEs1J0ModIs3pWNWmesjAq3rlmiez0,8177
15
- uiprotect/cli/viewers.py,sha256=SZlolZH3kkcWKjATrA37TCVZYRpF0t4cCccrC8vIv-M,2195
16
- uiprotect/data/__init__.py,sha256=38Kb1DVi4kv9FTTwugatPNSWLiIp6uvUlTMZRQp2jTY,3050
17
- uiprotect/data/base.py,sha256=YJ0iofoy1K3EG55npokU3T2CLRC8kctutfIy0Sq_6Sg,37850
18
- uiprotect/data/bootstrap.py,sha256=fyC6CoYnm90r1VAWSuOe8FFh8ULaGSv6jNMQcpKPBZA,21821
19
- uiprotect/data/convert.py,sha256=f8QkwZnlNbV_W-YognlDvZ1gQKp5yFuC50396hcu6DU,2127
20
- uiprotect/data/devices.py,sha256=3UOOzFXgJP7AOPKTE1SgPcLy37W4DmSNflIFiyi8tSE,111792
21
- uiprotect/data/nvr.py,sha256=JZja0QiT91Eu8-lw_M0Ora1KGNXhbG5dVNLN8YdeSw0,47677
22
- uiprotect/data/types.py,sha256=MTi9dVzKTp_8XtAmWKtbZujwE5plKGHdjglFGcJ4Yxs,15789
23
- uiprotect/data/user.py,sha256=HZJh9IOXS23kM-szTn7dGGsRZz9w2_9DqltL90gcMoE,7095
24
- uiprotect/data/websocket.py,sha256=3iU8hcH5GsVrGLoDjhXcv7zOKmXrMuQUqUud_ZsF6vw,6084
25
- uiprotect/exceptions.py,sha256=kgn0cRM6lTtgLza09SDa3ZiX6ue1QqHCOogQ4qu6KTQ,965
26
- uiprotect/py.typed,sha256=47DEQpj8HBSa-_TImW-5JCeuQeRkm5NMpJWZG3hSuFU,0
27
- uiprotect/release_cache.json,sha256=NamnSFy78hOWY0DPO87J9ELFCAN6NnVquv8gQO75ZG4,386
28
- uiprotect/stream.py,sha256=V4aJfVWpSUsWE1PQrXH8F7obQQi1ukPAZ7PzwABjt0I,4942
29
- uiprotect/test_util/__init__.py,sha256=sSEXu6_pwdYNQSCYtftpX1Dy1S8XYOvhrpECYRxeKJE,18596
30
- uiprotect/test_util/anonymize.py,sha256=AGYELhDC4BrdK0deI6zh5jFp3SuM_HvAWLeoxFHSiwg,8486
31
- uiprotect/utils.py,sha256=1HB-rtzdTxsRzEY_vnzdJZOzyruci7lOkQDfr8D1L_8,18244
32
- uiprotect/websocket.py,sha256=iMTdchymaCgVHsmY1bRbxkcymqt6WQircIHYNxCu178,7289
33
- uiprotect-0.5.0.dist-info/LICENSE,sha256=INx18jhdbVXMEiiBANeKEbrbz57ckgzxk5uutmmcxGk,1111
34
- uiprotect-0.5.0.dist-info/METADATA,sha256=lofryisrm6u9ASPQ0r77MqHKRqWNUE1XkAzuUrlBBYI,10984
35
- uiprotect-0.5.0.dist-info/WHEEL,sha256=sP946D7jFCHeNz5Iq4fL4Lu-PrWrFsgfLXbbkciIZwg,88
36
- uiprotect-0.5.0.dist-info/entry_points.txt,sha256=J78AUTPrTTxgI3s7SVgrmGqDP7piX2wuuEORzhDdVRA,47
37
- uiprotect-0.5.0.dist-info/RECORD,,