plexus-python 0.7.0__py3-none-any.whl → 0.7.1__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.
plexus/__init__.py CHANGED
@@ -10,5 +10,5 @@ Plexus — thin Python SDK for sending telemetry to the Plexus gateway.
10
10
  from plexus.client import Plexus, PlexusError, AuthenticationError, read_mjpeg_frames
11
11
  from plexus.config import RetryConfig
12
12
 
13
- __version__ = "0.7.0"
13
+ __version__ = "0.7.1"
14
14
  __all__ = ["Plexus", "PlexusError", "AuthenticationError", "RetryConfig", "read_mjpeg_frames"]
plexus/client.py CHANGED
@@ -55,9 +55,7 @@ from plexus.config import (
55
55
  get_endpoint,
56
56
  get_gateway_url,
57
57
  get_gateway_ws_url,
58
- get_install_id,
59
58
  get_source_id,
60
- set_source_id,
61
59
  )
62
60
 
63
61
  logger = logging.getLogger(__name__)
@@ -414,9 +412,7 @@ class Plexus:
414
412
  api_key=self.api_key,
415
413
  source_id=self.source_id,
416
414
  ws_url=self._ws_url,
417
- install_id=get_install_id(),
418
415
  agent_version=__version__,
419
- on_source_id_assigned=self._on_source_id_assigned,
420
416
  on_clock_synced=self._on_clock_synced,
421
417
  )
422
418
  self._ws.start()
@@ -428,16 +424,6 @@ class Plexus:
428
424
  def _on_clock_synced(self, offset_ms: int) -> None:
429
425
  self._clock_offset_ms = offset_ms
430
426
 
431
- def _on_source_id_assigned(self, assigned: str) -> None:
432
- """Callback from WebSocketTransport when the gateway returns an
433
- auto-suffixed source_id. Persists it so subsequent runs (and the HTTP
434
- fallback path in this process) use the assigned name directly."""
435
- self.source_id = assigned
436
- try:
437
- set_source_id(assigned)
438
- except Exception as e: # pragma: no cover - persistence failure is non-fatal
439
- logger.debug("failed to persist assigned source_id: %s", e)
440
-
441
427
  def _encode_frame(self, frame, quality: int) -> Tuple[bytes, int, int]:
442
428
  """Normalize any supported frame type to (jpeg_bytes, width, height).
443
429
 
plexus/config.py CHANGED
@@ -145,54 +145,6 @@ def get_source_id() -> Optional[str]:
145
145
  return source_id
146
146
 
147
147
 
148
- def get_install_id() -> str:
149
- """Get the device install ID, generating one if not set.
150
-
151
- The install_id is a stable per-installation UUID. It is generated lazily
152
- on first run (NOT at image-build time) so that cloned SD-card images
153
- naturally get distinct install_ids on their first boot. The gateway uses
154
- it to tell "same device reconnecting" from "different device claiming the
155
- same name" when resolving source_id collisions.
156
-
157
- Resolution order:
158
- 1. ``PLEXUS_INSTALL_ID`` env var — lets ephemeral containers (Fly
159
- machines, CI runners, Kubernetes pods) pin a stable identity
160
- across restarts when the config filesystem is ephemeral. Without
161
- this, every redeploy generates a new install_id and the gateway
162
- auto-suffixes the source_id to avoid a collision with the prior
163
- install ("gw-001" → "gw-001_2" → "gw-001_3"…).
164
- 2. ``install_id`` in the on-disk config.
165
- 3. Newly-generated UUID, persisted to config.
166
- """
167
- env_id = os.environ.get("PLEXUS_INSTALL_ID", "").strip()
168
- if env_id:
169
- return env_id
170
-
171
- config = load_config()
172
- install_id = config.get("install_id")
173
-
174
- if not install_id:
175
- import uuid
176
- install_id = uuid.uuid4().hex
177
- config["install_id"] = install_id
178
- save_config(config)
179
-
180
- return install_id
181
-
182
-
183
- def set_source_id(source_id: str) -> None:
184
- """Persist an updated source_id to the config file.
185
-
186
- Called by the SDK when the gateway returns an auto-suffixed name so the
187
- assigned name is stable across reconnects.
188
- """
189
- config = load_config()
190
- if config.get("source_id") == source_id:
191
- return
192
- config["source_id"] = source_id
193
- save_config(config)
194
-
195
-
196
148
  def get_persistent_buffer() -> bool:
197
149
  """Get persistent buffer setting. Default True (store-and-forward enabled)."""
198
150
  config = load_config()
plexus/ws.py CHANGED
@@ -89,11 +89,9 @@ class WebSocketTransport:
89
89
  source_id: str,
90
90
  ws_url: str,
91
91
  *,
92
- install_id: str = "",
93
92
  agent_version: str = "0.0.0",
94
93
  platform: str = "python-sdk",
95
94
  auto_reconnect: bool = True,
96
- on_source_id_assigned: Optional[Callable[[str], None]] = None,
97
95
  on_clock_synced: Optional[Callable[[int], None]] = None,
98
96
  ):
99
97
  if not api_key:
@@ -103,12 +101,10 @@ class WebSocketTransport:
103
101
 
104
102
  self.api_key = api_key
105
103
  self.source_id = source_id
106
- self.install_id = install_id
107
104
  self.ws_url = _ensure_device_path(ws_url)
108
105
  self.agent_version = agent_version
109
106
  self.platform = platform
110
107
  self.auto_reconnect = auto_reconnect
111
- self._on_source_id_assigned = on_source_id_assigned
112
108
  self._on_clock_synced = on_clock_synced
113
109
 
114
110
  self._commands: Dict[str, _RegisteredCommand] = {}
@@ -278,16 +274,13 @@ class WebSocketTransport:
278
274
  self._ws = ws
279
275
 
280
276
  # 1. Send device_auth
281
- desired_source_id = self.source_id
282
277
  auth = {
283
278
  "type": "device_auth",
284
279
  "api_key": self.api_key,
285
- "source_id": desired_source_id,
280
+ "source_id": self.source_id,
286
281
  "platform": self.platform,
287
282
  "agent_version": self.agent_version,
288
283
  }
289
- if self.install_id:
290
- auth["install_id"] = self.install_id
291
284
  if self._commands:
292
285
  auth["commands"] = [c.to_manifest() for c in self._commands.values()]
293
286
  ws.send(json.dumps(auth))
@@ -312,22 +305,6 @@ class WebSocketTransport:
312
305
  except Exception as e:
313
306
  logger.debug("on_clock_synced callback raised: %s", e)
314
307
 
315
- # The gateway may return a different source_id if the desired name
316
- # was already claimed by another install — adopt the assigned value
317
- # so all subsequent frames (heartbeats, future reconnects) use it.
318
- assigned = msg.get("source_id")
319
- if isinstance(assigned, str) and assigned and assigned != self.source_id:
320
- logger.info(
321
- "plexus ws source_id auto-suffixed: requested=%s assigned=%s",
322
- desired_source_id, assigned,
323
- )
324
- self.source_id = assigned
325
- if self._on_source_id_assigned is not None:
326
- try:
327
- self._on_source_id_assigned(assigned)
328
- except Exception as e: # pragma: no cover - callback errors must not break auth
329
- logger.debug("on_source_id_assigned callback raised: %s", e)
330
-
331
308
  was_reconnect = self._backoff_attempt > 0
332
309
  self._authenticated.set()
333
310
  self._backoff_attempt = 0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.4
2
2
  Name: plexus-python
3
- Version: 0.7.0
3
+ Version: 0.7.1
4
4
  Summary: Thin Python SDK for Plexus — send telemetry in one line
5
5
  Project-URL: Homepage, https://plexus.dev
6
6
  Project-URL: Documentation, https://docs.plexus.dev
@@ -0,0 +1,14 @@
1
+ plexus/__init__.py,sha256=ZzZDGRCztNWGUtN-YF1EwwYzngxsZkU9zb_rW1Tfalg,447
2
+ plexus/_log.py,sha256=3fjXrHFZghQ_17umMcvDUjjTH6aTQB3J4SpVDBiH03w,335
3
+ plexus/buffer.py,sha256=0i6PLgoj904jFNv9RCrlskvPQsPSu_KNdYWMasFOvsg,9596
4
+ plexus/cli.py,sha256=-2wvHXQzobx3_tDGTXpaE2PlHv884y93Mu29kZE8qZE,14214
5
+ plexus/client.py,sha256=SZ4V9FN-bt3QKqVgp9S5QKdRXw934WXZxKlYUb7bWHw,35810
6
+ plexus/config.py,sha256=RNym2Fon6JOCVi1rXPSRWjPFAdT8DSmokY5JPEljQOc,4450
7
+ plexus/ws.py,sha256=9DiQchqCQU7O8r8-FuqotJh8vYAQBO7npJn4BFNzLAE,16242
8
+ plexus/cameras/__init__.py,sha256=OvnU9KGKxkVtFLlk56H9x-ATa6UvpLI7PANa0HQO2cc,490
9
+ plexus/cameras/thermal.py,sha256=7o33QsF1RiZLManTxZ2E36nO8lRAHppCDkS3zXBHCxs,12047
10
+ plexus_python-0.7.1.dist-info/METADATA,sha256=OUDqqIIcHUaZms1QCwL7XdaFo6j11LeN0HZ3EipZEIM,11739
11
+ plexus_python-0.7.1.dist-info/WHEEL,sha256=mffPy8wBnZQn2VnJUU5jE99KsxaSfiyMHV9Yt0aLVxs,87
12
+ plexus_python-0.7.1.dist-info/entry_points.txt,sha256=YlkOtTn_7Q_IGuJaKdvpU-90dCeBSPx2p_UTGMAz5Zs,43
13
+ plexus_python-0.7.1.dist-info/licenses/LICENSE,sha256=nm3qP1F-JAGcfLpRVtIX24L20LMnRpxmZ2oKZzFpLVo,10755
14
+ plexus_python-0.7.1.dist-info/RECORD,,
@@ -1,4 +1,4 @@
1
1
  Wheel-Version: 1.0
2
- Generator: hatchling 1.29.0
2
+ Generator: hatchling 1.30.1
3
3
  Root-Is-Purelib: true
4
4
  Tag: py3-none-any
@@ -1,14 +0,0 @@
1
- plexus/__init__.py,sha256=HNRVhpDrkyyT-SQqfFzNf3E_uwbwQA-XcDKPoBytdEo,447
2
- plexus/_log.py,sha256=3fjXrHFZghQ_17umMcvDUjjTH6aTQB3J4SpVDBiH03w,335
3
- plexus/buffer.py,sha256=0i6PLgoj904jFNv9RCrlskvPQsPSu_KNdYWMasFOvsg,9596
4
- plexus/cli.py,sha256=-2wvHXQzobx3_tDGTXpaE2PlHv884y93Mu29kZE8qZE,14214
5
- plexus/client.py,sha256=DaCPURIhVswwjf4oGrp381Atiy02gk3viLy6NioBAtQ,36480
6
- plexus/config.py,sha256=wsG6lhNLmKe3JRlVycyRUKQeywnPUPPfrWkXFxYwELE,6179
7
- plexus/ws.py,sha256=_c--U-yySZbMXZsaj0fUaYKF_WesolHsrMDx4oWYfFQ,17428
8
- plexus/cameras/__init__.py,sha256=OvnU9KGKxkVtFLlk56H9x-ATa6UvpLI7PANa0HQO2cc,490
9
- plexus/cameras/thermal.py,sha256=7o33QsF1RiZLManTxZ2E36nO8lRAHppCDkS3zXBHCxs,12047
10
- plexus_python-0.7.0.dist-info/METADATA,sha256=tlsktssdsOI7dyA7O2I6azPay2Xj998Z4zNxbFf4H6s,11739
11
- plexus_python-0.7.0.dist-info/WHEEL,sha256=QccIxa26bgl1E6uMy58deGWi-0aeIkkangHcxk2kWfw,87
12
- plexus_python-0.7.0.dist-info/entry_points.txt,sha256=YlkOtTn_7Q_IGuJaKdvpU-90dCeBSPx2p_UTGMAz5Zs,43
13
- plexus_python-0.7.0.dist-info/licenses/LICENSE,sha256=nm3qP1F-JAGcfLpRVtIX24L20LMnRpxmZ2oKZzFpLVo,10755
14
- plexus_python-0.7.0.dist-info/RECORD,,