rtls-sdk 0.6.3__tar.gz → 0.7.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.
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/CHANGELOG.md +14 -1
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/PKG-INFO +2 -2
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/pyproject.toml +12 -2
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/__init__.py +4 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/__init__.py +3 -0
- rtls_sdk-0.7.0/src/rtls_sdk/models/zone_download_status.py +51 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/zones.py +47 -1
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/.gitignore +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/LICENSE +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/README.md +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/_auth.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/_client.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/_envelope.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/_http.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/_logging.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/_pagination.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/_query.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/_time.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/_ws.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/compounds/__init__.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/compounds/auth.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/compounds/context.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/compounds/groups.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/compounds/nodes.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/compounds/reports.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/compounds/system.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/compounds/tags.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/compounds/users.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/compounds/zones.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/errors.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/_base.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/alarm.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/anchor.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/anchor_association.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/area.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/bulk.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/company.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/csv_blob.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/floorplan.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/group.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/heatmap.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/import_result.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/lsb_settings.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/network.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/node.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/node_params.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/notification.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/position.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/project.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/pws.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/report.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/schedule.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/session_context.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/site.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/subscriber.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/system.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/system_health.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/tag.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/tag_association.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/tag_template.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/user.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/ws/__init__.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/ws/_base.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/ws/alarm.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/ws/notify.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/ws/ota.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/ws/param_p.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/ws/position.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/ws/sensor.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/ws/user_msg.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/ws/zone_event.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/zone.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/models/zone_event.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/py.typed +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/__init__.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/_base.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/alarms.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/anchor_associations.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/anchors.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/areas.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/auth.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/companies.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/context.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/events.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/floorplans.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/groups.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/logger.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/lsb.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/messaging.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/network.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/nodes.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/notifications.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/projects.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/reports.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/schedules.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/sites.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/subscribers.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/system.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/tag_associations.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/tags.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/user_messages.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/users.py +0 -0
- {rtls_sdk-0.6.3 → rtls_sdk-0.7.0}/src/rtls_sdk/resources/ws.py +0 -0
|
@@ -5,7 +5,20 @@ All notable changes to the RTLS SDK will be documented in this file.
|
|
|
5
5
|
The format is based on [Keep a Changelog](https://keepachangelog.com/en/1.1.0/)
|
|
6
6
|
and this project adheres to [Semantic Versioning](https://semver.org/).
|
|
7
7
|
|
|
8
|
-
## [
|
|
8
|
+
## [0.7.0] — 2026-10-20
|
|
9
|
+
|
|
10
|
+
### Added
|
|
11
|
+
|
|
12
|
+
- `zones.download_request(tag_uids, *, action="UPDATE")` — trigger (or
|
|
13
|
+
verify) the SZM→tag zone-download wire push (`POST /api/zone_download_request`).
|
|
14
|
+
- `zones.download_status(tag_uid=None)` — per-tag zone-download sync status
|
|
15
|
+
(`GET /api/zone_download_status[/:uid]`), returned as a list of the new
|
|
16
|
+
`ZoneDownloadStatus` model (`download_status` one of `OUTDATED`,
|
|
17
|
+
`IN_PROCESS`, `UPDATED`, `OOSYNC`; `tag_uid` is the SDK-canonical name
|
|
18
|
+
for the server's `trackable_uid`, mapped on read per the `0.6.2`
|
|
19
|
+
trackable→tag convention). Both endpoints already existed server-side
|
|
20
|
+
(`rtls-frontend`'s `zone_manager` addon) — the SDK simply had no client
|
|
21
|
+
for them.
|
|
9
22
|
|
|
10
23
|
## [0.6.3] — 2026-09-10
|
|
11
24
|
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.5
|
|
2
2
|
Name: rtls-sdk
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.7.0
|
|
4
4
|
Summary: Python SDK for the RTLS REST API
|
|
5
5
|
Project-URL: Documentation, https://rtls-sdk.pages.dev
|
|
6
6
|
Author: RTLS SDK Maintainers
|
|
@@ -26,7 +26,7 @@ Requires-Dist: pytest-httpserver>=1.0; extra == 'dev'
|
|
|
26
26
|
Requires-Dist: pytest>=7.4; extra == 'dev'
|
|
27
27
|
Requires-Dist: python-dotenv>=1.0; extra == 'dev'
|
|
28
28
|
Requires-Dist: respx>=0.20; extra == 'dev'
|
|
29
|
-
Requires-Dist: ruff
|
|
29
|
+
Requires-Dist: ruff<0.13,>=0.12.7; extra == 'dev'
|
|
30
30
|
Provides-Extra: docs
|
|
31
31
|
Requires-Dist: mkdocs-material>=9; extra == 'docs'
|
|
32
32
|
Requires-Dist: mkdocstrings[python]>=0.24; extra == 'docs'
|
|
@@ -4,7 +4,7 @@ build-backend = "hatchling.build"
|
|
|
4
4
|
|
|
5
5
|
[project]
|
|
6
6
|
name = "rtls-sdk"
|
|
7
|
-
version = "0.
|
|
7
|
+
version = "0.7.0"
|
|
8
8
|
description = "Python SDK for the RTLS REST API"
|
|
9
9
|
readme = "README.md"
|
|
10
10
|
requires-python = ">=3.10"
|
|
@@ -33,7 +33,12 @@ dev = [
|
|
|
33
33
|
"pytest-cov>=4.1",
|
|
34
34
|
"respx>=0.20",
|
|
35
35
|
"pytest-httpserver>=1.0",
|
|
36
|
-
|
|
36
|
+
# Pinned deliberately, not floored. CI installs `[dev]` fresh on every run, so an
|
|
37
|
+
# unpinned linter makes the gate a function of the release calendar: ruff 0.16
|
|
38
|
+
# turned on rules this code has never satisfied and changed the formatter, and
|
|
39
|
+
# CI went red on a commit nobody had touched since July. Bump this on purpose,
|
|
40
|
+
# in its own PR, with the resulting fixes.
|
|
41
|
+
"ruff>=0.12.7,<0.13",
|
|
37
42
|
"mypy>=1.8",
|
|
38
43
|
"python-dotenv>=1.0",
|
|
39
44
|
]
|
|
@@ -67,6 +72,11 @@ extend-select = ["E", "F", "I", "UP", "B", "SIM", "RUF"]
|
|
|
67
72
|
ignore = [
|
|
68
73
|
"B008", # function call in default argument — pydantic uses this idiom
|
|
69
74
|
"SIM108", # ternary not always more readable
|
|
75
|
+
# `isinstance(x, (A, B))` over `isinstance(x, A | B)`. Ruff removed this rule
|
|
76
|
+
# after 0.12 — the tuple form is faster at runtime and reads no worse — so this
|
|
77
|
+
# ignore matches what the rule's own authors concluded, and keeps the pinned
|
|
78
|
+
# gate green without rewriting three call sites to be slower.
|
|
79
|
+
"UP038",
|
|
70
80
|
]
|
|
71
81
|
|
|
72
82
|
[tool.ruff.lint.per-file-ignores]
|
|
@@ -75,6 +75,8 @@ from .models import (
|
|
|
75
75
|
Version,
|
|
76
76
|
WsHost,
|
|
77
77
|
Zone,
|
|
78
|
+
ZoneDownloadState,
|
|
79
|
+
ZoneDownloadStatus,
|
|
78
80
|
ZoneEvent,
|
|
79
81
|
)
|
|
80
82
|
from .models.ws import (
|
|
@@ -173,5 +175,7 @@ __all__ = [ # noqa: RUF022 — grouped logically, not alphabetically
|
|
|
173
175
|
"Version",
|
|
174
176
|
"WsHost",
|
|
175
177
|
"Zone",
|
|
178
|
+
"ZoneDownloadState",
|
|
179
|
+
"ZoneDownloadStatus",
|
|
176
180
|
"ZoneEvent",
|
|
177
181
|
]
|
|
@@ -31,6 +31,7 @@ from .tag_association import TagAssociation
|
|
|
31
31
|
from .tag_template import TagTemplate
|
|
32
32
|
from .user import Role, User, UserFlags
|
|
33
33
|
from .zone import Zone
|
|
34
|
+
from .zone_download_status import ZoneDownloadState, ZoneDownloadStatus
|
|
34
35
|
from .zone_event import ZoneEvent
|
|
35
36
|
|
|
36
37
|
__all__ = [
|
|
@@ -81,5 +82,7 @@ __all__ = [
|
|
|
81
82
|
"Version",
|
|
82
83
|
"WsHost",
|
|
83
84
|
"Zone",
|
|
85
|
+
"ZoneDownloadState",
|
|
86
|
+
"ZoneDownloadStatus",
|
|
84
87
|
"ZoneEvent",
|
|
85
88
|
]
|
|
@@ -0,0 +1,51 @@
|
|
|
1
|
+
"""Zone-download sync-status model.
|
|
2
|
+
|
|
3
|
+
Tracks whether a tag's zone-download push (SZM → tag LZM) has synced.
|
|
4
|
+
The server's own status vocabulary (``server/addons/zone_manager/constants.js``)
|
|
5
|
+
is kept verbatim rather than translated to an SDK-canonical spelling,
|
|
6
|
+
since callers compare against it directly (e.g. polling until
|
|
7
|
+
``"UPDATED"``).
|
|
8
|
+
"""
|
|
9
|
+
|
|
10
|
+
from __future__ import annotations
|
|
11
|
+
|
|
12
|
+
from datetime import datetime
|
|
13
|
+
from typing import Any, Literal
|
|
14
|
+
|
|
15
|
+
from pydantic import model_validator
|
|
16
|
+
|
|
17
|
+
from ._base import _BaseModel
|
|
18
|
+
|
|
19
|
+
ZoneDownloadState = Literal["OUTDATED", "IN_PROCESS", "UPDATED", "OOSYNC"]
|
|
20
|
+
|
|
21
|
+
|
|
22
|
+
class ZoneDownloadStatus(_BaseModel):
|
|
23
|
+
"""A tag's current zone-download sync status.
|
|
24
|
+
|
|
25
|
+
``tag_uid`` is the SDK-canonical name for the server's
|
|
26
|
+
``trackable_uid`` wire field (mirroring :class:`Alarm` / :class:`Zone`);
|
|
27
|
+
the raw wire payload remains available via ``.raw``. ``download_status``
|
|
28
|
+
is one of the server's literal ``ZONE_DOWNLOAD_STATUS`` values.
|
|
29
|
+
``reason`` and ``sync_requested`` are present on some rows and absent
|
|
30
|
+
on others (server returns whatever the underlying row has); both
|
|
31
|
+
default to ``None``.
|
|
32
|
+
"""
|
|
33
|
+
|
|
34
|
+
tag_uid: str
|
|
35
|
+
download_status: ZoneDownloadState
|
|
36
|
+
ts: datetime | None = None
|
|
37
|
+
reason: str | None = None
|
|
38
|
+
sync_requested: bool | None = None
|
|
39
|
+
|
|
40
|
+
@model_validator(mode="before")
|
|
41
|
+
@classmethod
|
|
42
|
+
def _map_wire_aliases(cls, data: Any) -> Any:
|
|
43
|
+
if not isinstance(data, dict):
|
|
44
|
+
return data
|
|
45
|
+
out = dict(data)
|
|
46
|
+
if out.get("tag_uid") is None and out.get("trackable_uid") is not None:
|
|
47
|
+
out["tag_uid"] = out["trackable_uid"]
|
|
48
|
+
return out
|
|
49
|
+
|
|
50
|
+
|
|
51
|
+
__all__ = ["ZoneDownloadState", "ZoneDownloadStatus"]
|
|
@@ -10,7 +10,7 @@ from .._time import to_epoch_ms
|
|
|
10
10
|
from ..compounds import zones as _compound
|
|
11
11
|
from ..compounds.tags import UNSET, _Unset
|
|
12
12
|
from ..errors import NotFound
|
|
13
|
-
from ..models import Zone
|
|
13
|
+
from ..models import Zone, ZoneDownloadStatus
|
|
14
14
|
from ._base import ResourceAPI
|
|
15
15
|
|
|
16
16
|
|
|
@@ -209,6 +209,52 @@ class ZonesAPI(ResourceAPI):
|
|
|
209
209
|
"""
|
|
210
210
|
_compound.delete_zone(self._client, uid)
|
|
211
211
|
|
|
212
|
+
def download_request(self, tag_uids: list[str], *, action: str = "UPDATE") -> str:
|
|
213
|
+
"""Trigger (or verify) a zone-download push to one or more tags.
|
|
214
|
+
|
|
215
|
+
Wraps ``POST /api/zone_download_request`` — the SZM→tag LZM
|
|
216
|
+
wire push, same action the SiteWise "start zone download"
|
|
217
|
+
button performs. ``action`` is ``"UPDATE"`` (the default, push
|
|
218
|
+
the current zone set) or ``"VERIFY"`` (ask the tag to report
|
|
219
|
+
back without pushing). The server contract is batch-shaped
|
|
220
|
+
(one or more tags per request) — pass a single-element list
|
|
221
|
+
for one tag.
|
|
222
|
+
|
|
223
|
+
Returns the server's own human-readable ``message`` string
|
|
224
|
+
(which entities were processed / rejected); poll
|
|
225
|
+
:meth:`download_status` for the actual per-tag sync outcome
|
|
226
|
+
rather than parsing this message.
|
|
227
|
+
"""
|
|
228
|
+
body = {
|
|
229
|
+
"zone_download_request": {
|
|
230
|
+
"action": action,
|
|
231
|
+
"trackables": [{"trackable_uid": uid} for uid in tag_uids],
|
|
232
|
+
}
|
|
233
|
+
}
|
|
234
|
+
response = self._post("/api/zone_download_request", json=body)
|
|
235
|
+
payload = response.json()
|
|
236
|
+
return payload.get("message", "") if isinstance(payload, dict) else ""
|
|
237
|
+
|
|
238
|
+
def download_status(self, tag_uid: str | None = None) -> list[ZoneDownloadStatus]:
|
|
239
|
+
"""Return per-tag zone-download sync status.
|
|
240
|
+
|
|
241
|
+
Wraps ``GET /api/zone_download_status`` (all tags) or
|
|
242
|
+
``GET /api/zone_download_status/{uid}`` (one tag, still
|
|
243
|
+
returned as a list — the server's own query is filtered, not
|
|
244
|
+
reshaped). Poll this after :meth:`download_request` until the
|
|
245
|
+
relevant row's ``download_status`` reads ``"UPDATED"`` (or
|
|
246
|
+
times out) — the request call itself does not block on the
|
|
247
|
+
wire push completing.
|
|
248
|
+
"""
|
|
249
|
+
path = (
|
|
250
|
+
"/api/zone_download_status"
|
|
251
|
+
if tag_uid is None
|
|
252
|
+
else f"/api/zone_download_status/{tag_uid}"
|
|
253
|
+
)
|
|
254
|
+
response = self._get(path)
|
|
255
|
+
items = unwrap_resource(response.json(), "zone_download_status")
|
|
256
|
+
return [ZoneDownloadStatus.from_wire(item) for item in items]
|
|
257
|
+
|
|
212
258
|
def list(self) -> list[Zone]:
|
|
213
259
|
"""Return zones and buffers for the current project.
|
|
214
260
|
|
|
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
|
|
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
|