edgesync 0.3.2__tar.gz → 0.3.3__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.
Files changed (68) hide show
  1. {edgesync-0.3.2 → edgesync-0.3.3}/CHANGELOG.md +9 -1
  2. {edgesync-0.3.2 → edgesync-0.3.3}/PKG-INFO +21 -23
  3. {edgesync-0.3.2 → edgesync-0.3.3}/README.md +19 -20
  4. edgesync-0.3.3/VERSION +1 -0
  5. {edgesync-0.3.2 → edgesync-0.3.3}/docs/getting-started.md +19 -20
  6. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/transports/mqtt.py +2 -9
  7. {edgesync-0.3.2 → edgesync-0.3.3}/pyproject.toml +1 -3
  8. {edgesync-0.3.2 → edgesync-0.3.3}/uv.lock +2 -7
  9. edgesync-0.3.2/VERSION +0 -1
  10. {edgesync-0.3.2 → edgesync-0.3.3}/.github/workflows/ci.yml +0 -0
  11. {edgesync-0.3.2 → edgesync-0.3.3}/.github/workflows/release.yml +0 -0
  12. {edgesync-0.3.2 → edgesync-0.3.3}/.gitignore +0 -0
  13. {edgesync-0.3.2 → edgesync-0.3.3}/CONTRIBUTING.md +0 -0
  14. {edgesync-0.3.2 → edgesync-0.3.3}/LICENSE +0 -0
  15. {edgesync-0.3.2 → edgesync-0.3.3}/SECURITY.md +0 -0
  16. {edgesync-0.3.2 → edgesync-0.3.3}/docs/integrations.md +0 -0
  17. {edgesync-0.3.2 → edgesync-0.3.3}/docs/reliability.md +0 -0
  18. {edgesync-0.3.2 → edgesync-0.3.3}/docs/storage.md +0 -0
  19. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/__init__.py +0 -0
  20. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/client.py +0 -0
  21. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/config.py +0 -0
  22. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/exceptions.py +0 -0
  23. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/logging.py +0 -0
  24. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/models/__init__.py +0 -0
  25. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/models/delivery.py +0 -0
  26. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/models/message.py +0 -0
  27. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/models/receipt.py +0 -0
  28. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/models/stats.py +0 -0
  29. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/py.typed +0 -0
  30. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/queue/__init__.py +0 -0
  31. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/queue/manager.py +0 -0
  32. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/retry/__init__.py +0 -0
  33. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/retry/backoff.py +0 -0
  34. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/retry/policy.py +0 -0
  35. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/storage/__init__.py +0 -0
  36. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/storage/base.py +0 -0
  37. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/storage/migrations.py +0 -0
  38. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/storage/sqlite.py +0 -0
  39. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/transports/__init__.py +0 -0
  40. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/transports/base.py +0 -0
  41. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/transports/http.py +0 -0
  42. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/transports/registry.py +0 -0
  43. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/utils/__init__.py +0 -0
  44. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/utils/clock.py +0 -0
  45. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/utils/ids.py +0 -0
  46. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/worker/__init__.py +0 -0
  47. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/worker/lifecycle.py +0 -0
  48. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/worker/scheduler.py +0 -0
  49. {edgesync-0.3.2 → edgesync-0.3.3}/edgesync/worker/sync_worker.py +0 -0
  50. {edgesync-0.3.2 → edgesync-0.3.3}/tests/__init__.py +0 -0
  51. {edgesync-0.3.2 → edgesync-0.3.3}/tests/conftest.py +0 -0
  52. {edgesync-0.3.2 → edgesync-0.3.3}/tests/fixtures/__init__.py +0 -0
  53. {edgesync-0.3.2 → edgesync-0.3.3}/tests/fixtures/factories.py +0 -0
  54. {edgesync-0.3.2 → edgesync-0.3.3}/tests/fixtures/fake_transport.py +0 -0
  55. {edgesync-0.3.2 → edgesync-0.3.3}/tests/integration/__init__.py +0 -0
  56. {edgesync-0.3.2 → edgesync-0.3.3}/tests/integration/test_client.py +0 -0
  57. {edgesync-0.3.2 → edgesync-0.3.3}/tests/integration/test_http_transport.py +0 -0
  58. {edgesync-0.3.2 → edgesync-0.3.3}/tests/integration/test_mqtt_transport.py +0 -0
  59. {edgesync-0.3.2 → edgesync-0.3.3}/tests/integration/test_sqlite_storage.py +0 -0
  60. {edgesync-0.3.2 → edgesync-0.3.3}/tests/integration/test_worker.py +0 -0
  61. {edgesync-0.3.2 → edgesync-0.3.3}/tests/reliability/__init__.py +0 -0
  62. {edgesync-0.3.2 → edgesync-0.3.3}/tests/reliability/test_reliability.py +0 -0
  63. {edgesync-0.3.2 → edgesync-0.3.3}/tests/unit/__init__.py +0 -0
  64. {edgesync-0.3.2 → edgesync-0.3.3}/tests/unit/test_backoff.py +0 -0
  65. {edgesync-0.3.2 → edgesync-0.3.3}/tests/unit/test_config.py +0 -0
  66. {edgesync-0.3.2 → edgesync-0.3.3}/tests/unit/test_models.py +0 -0
  67. {edgesync-0.3.2 → edgesync-0.3.3}/tests/unit/test_queue_manager.py +0 -0
  68. {edgesync-0.3.2 → edgesync-0.3.3}/tests/unit/test_retry_policy.py +0 -0
@@ -7,6 +7,13 @@ project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
7
7
 
8
8
  ## [Unreleased]
9
9
 
10
+ ## [0.3.3] - 2026-09-13
11
+
12
+ ### Changed
13
+
14
+ - `aiomqtt` is now a required dependency instead of an optional `mqtt` extra, so
15
+ `pip install edgesync` alone is enough to use `MQTTTransport`.
16
+
10
17
  ## [0.3.2] - 2026-08-24
11
18
 
12
19
  ### Added
@@ -97,7 +104,8 @@ project adheres to [Semantic Versioning](https://semver.org/spec/v2.0.0.html).
97
104
  - Crash and restart recovery via expired-lease sweeps, safe across concurrent workers and
98
105
  processes sharing the same database file.
99
106
 
100
- [Unreleased]: https://github.com/adhuldas/EdgeSync/compare/v0.3.2...HEAD
107
+ [Unreleased]: https://github.com/adhuldas/EdgeSync/compare/v0.3.3...HEAD
108
+ [0.3.3]: https://github.com/adhuldas/EdgeSync/compare/v0.3.2...v0.3.3
101
109
  [0.3.2]: https://github.com/adhuldas/EdgeSync/compare/v0.3.1...v0.3.2
102
110
  [0.3.1]: https://github.com/adhuldas/EdgeSync/compare/v0.3.0...v0.3.1
103
111
  [0.3.0]: https://github.com/adhuldas/EdgeSync/compare/v0.2.1...v0.3.0
@@ -1,6 +1,6 @@
1
1
  Metadata-Version: 2.5
2
2
  Name: edgesync
3
- Version: 0.3.2
3
+ Version: 0.3.3
4
4
  Summary: Reliable data delivery for unreliable networks.
5
5
  Project-URL: Homepage, https://github.com/adhuldas/EdgeSync
6
6
  Project-URL: Repository, https://github.com/adhuldas/EdgeSync
@@ -25,10 +25,9 @@ Classifier: Topic :: Software Development :: Libraries :: Python Modules
25
25
  Classifier: Topic :: System :: Distributed Computing
26
26
  Classifier: Typing :: Typed
27
27
  Requires-Python: >=3.10
28
+ Requires-Dist: aiomqtt<3,>=2.5
28
29
  Requires-Dist: aiosqlite>=0.20
29
30
  Requires-Dist: httpx>=0.27
30
- Provides-Extra: mqtt
31
- Requires-Dist: aiomqtt<3,>=2.5; extra == 'mqtt'
32
31
  Description-Content-Type: text/markdown
33
32
 
34
33
  # EdgeSync
@@ -96,33 +95,32 @@ caller needing to stay connected or wait for the network.
96
95
 
97
96
  ## MQTT
98
97
 
99
- Install the optional extra first:
100
-
101
- ```bash
102
- pip install edgesync[mqtt]
103
- ```
104
-
105
98
  Publishing to MQTT instead of HTTP is the same pattern with a different transport:
106
99
 
107
100
  ```python
101
+ import asyncio
108
102
  from edgesync import EdgeSync
109
103
  from edgesync.transports.mqtt import MQTTTransport
110
104
 
111
- sync = EdgeSync(
112
- database="edgesync.db",
113
- destinations={
114
- "telemetry": MQTTTransport(
115
- "broker.example.com",
116
- "devices/device-001/telemetry",
117
- qos=1,
118
- username="device-001",
119
- password="...",
120
- ),
121
- },
122
- default_destination="telemetry",
123
- )
124
105
 
125
- await sync.publish({"temperature": 28.5})
106
+ async def main():
107
+ async with EdgeSync(
108
+ database="edgesync.db",
109
+ destinations={
110
+ "telemetry": MQTTTransport(
111
+ "broker.example.com",
112
+ "devices/device-001/telemetry",
113
+ qos=1,
114
+ username="device-001",
115
+ password="...",
116
+ ),
117
+ },
118
+ default_destination="telemetry",
119
+ ) as sync:
120
+ await sync.publish({"temperature": 28.5})
121
+
122
+
123
+ asyncio.run(main())
126
124
  ```
127
125
 
128
126
  `MQTTTransport` only accepts QoS 1 or 2 — QoS 0 publishes are never acknowledged by the
@@ -63,33 +63,32 @@ caller needing to stay connected or wait for the network.
63
63
 
64
64
  ## MQTT
65
65
 
66
- Install the optional extra first:
67
-
68
- ```bash
69
- pip install edgesync[mqtt]
70
- ```
71
-
72
66
  Publishing to MQTT instead of HTTP is the same pattern with a different transport:
73
67
 
74
68
  ```python
69
+ import asyncio
75
70
  from edgesync import EdgeSync
76
71
  from edgesync.transports.mqtt import MQTTTransport
77
72
 
78
- sync = EdgeSync(
79
- database="edgesync.db",
80
- destinations={
81
- "telemetry": MQTTTransport(
82
- "broker.example.com",
83
- "devices/device-001/telemetry",
84
- qos=1,
85
- username="device-001",
86
- password="...",
87
- ),
88
- },
89
- default_destination="telemetry",
90
- )
91
73
 
92
- await sync.publish({"temperature": 28.5})
74
+ async def main():
75
+ async with EdgeSync(
76
+ database="edgesync.db",
77
+ destinations={
78
+ "telemetry": MQTTTransport(
79
+ "broker.example.com",
80
+ "devices/device-001/telemetry",
81
+ qos=1,
82
+ username="device-001",
83
+ password="...",
84
+ ),
85
+ },
86
+ default_destination="telemetry",
87
+ ) as sync:
88
+ await sync.publish({"temperature": 28.5})
89
+
90
+
91
+ asyncio.run(main())
93
92
  ```
94
93
 
95
94
  `MQTTTransport` only accepts QoS 1 or 2 — QoS 0 publishes are never acknowledged by the
edgesync-0.3.3/VERSION ADDED
@@ -0,0 +1 @@
1
+ 0.3.3
@@ -126,31 +126,30 @@ than HTTP.
126
126
 
127
127
  ## MQTT
128
128
 
129
- Install the optional extra first:
130
-
131
- ```bash
132
- pip install edgesync[mqtt]
133
- ```
134
-
135
129
  ```python
130
+ import asyncio
136
131
  from edgesync import EdgeSync
137
132
  from edgesync.transports.mqtt import MQTTTransport
138
133
 
139
- sync = EdgeSync(
140
- database="edgesync.db",
141
- destinations={
142
- "telemetry": MQTTTransport(
143
- "broker.example.com",
144
- "devices/device-001/telemetry",
145
- qos=1,
146
- username="device-001",
147
- password="...",
148
- ),
149
- },
150
- default_destination="telemetry",
151
- )
152
134
 
153
- await sync.publish({"temperature": 28.5})
135
+ async def main():
136
+ async with EdgeSync(
137
+ database="edgesync.db",
138
+ destinations={
139
+ "telemetry": MQTTTransport(
140
+ "broker.example.com",
141
+ "devices/device-001/telemetry",
142
+ qos=1,
143
+ username="device-001",
144
+ password="...",
145
+ ),
146
+ },
147
+ default_destination="telemetry",
148
+ ) as sync:
149
+ await sync.publish({"temperature": 28.5})
150
+
151
+
152
+ asyncio.run(main())
154
153
  ```
155
154
 
156
155
  `MQTTTransport` only accepts QoS 1 or 2 — QoS 0 publishes are never acknowledged by the
@@ -1,7 +1,5 @@
1
1
  """MQTT transport backed by ``aiomqtt``.
2
2
 
3
- Requires the optional ``aiomqtt`` dependency: ``pip install edgesync[mqtt]``.
4
-
5
3
  Unlike :class:`~edgesync.transports.http.HTTPTransport`, MQTT is a stateful,
6
4
  persistent connection rather than a per-request protocol, which shapes two
7
5
  design decisions here:
@@ -22,18 +20,13 @@ from __future__ import annotations
22
20
  import contextlib
23
21
  import json
24
22
 
23
+ import aiomqtt
24
+
25
25
  from edgesync.logging import logger
26
26
  from edgesync.models.delivery import DeliveryResult
27
27
  from edgesync.models.message import Message
28
28
  from edgesync.transports.base import Transport
29
29
 
30
- try:
31
- import aiomqtt
32
- except ImportError as exc: # pragma: no cover - exercised only without the extra installed
33
- raise ImportError(
34
- "MQTTTransport requires the 'aiomqtt' package. Install it with: pip install edgesync[mqtt]"
35
- ) from exc
36
-
37
30
 
38
31
  class MQTTTransport(Transport):
39
32
  """Publish messages as JSON payloads to a fixed MQTT topic.
@@ -23,11 +23,9 @@ classifiers = [
23
23
  dependencies = [
24
24
  "httpx>=0.27",
25
25
  "aiosqlite>=0.20",
26
+ "aiomqtt>=2.5,<3",
26
27
  ]
27
28
 
28
- [project.optional-dependencies]
29
- mqtt = ["aiomqtt>=2.5,<3"]
30
-
31
29
  [project.urls]
32
30
  Homepage = "https://github.com/adhuldas/EdgeSync"
33
31
  Repository = "https://github.com/adhuldas/EdgeSync"
@@ -270,15 +270,11 @@ toml = [
270
270
  name = "edgesync"
271
271
  source = { editable = "." }
272
272
  dependencies = [
273
+ { name = "aiomqtt" },
273
274
  { name = "aiosqlite" },
274
275
  { name = "httpx" },
275
276
  ]
276
277
 
277
- [package.optional-dependencies]
278
- mqtt = [
279
- { name = "aiomqtt" },
280
- ]
281
-
282
278
  [package.dev-dependencies]
283
279
  dev = [
284
280
  { name = "mypy" },
@@ -291,11 +287,10 @@ dev = [
291
287
 
292
288
  [package.metadata]
293
289
  requires-dist = [
294
- { name = "aiomqtt", marker = "extra == 'mqtt'", specifier = ">=2.5,<3" },
290
+ { name = "aiomqtt", specifier = ">=2.5,<3" },
295
291
  { name = "aiosqlite", specifier = ">=0.20" },
296
292
  { name = "httpx", specifier = ">=0.27" },
297
293
  ]
298
- provides-extras = ["mqtt"]
299
294
 
300
295
  [package.metadata.requires-dev]
301
296
  dev = [
edgesync-0.3.2/VERSION DELETED
@@ -1 +0,0 @@
1
- 0.3.2
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