offline-sync-sdk 0.2.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.
Files changed (50) hide show
  1. offline_sync_sdk-0.2.0/.github/workflows/ci.yml +70 -0
  2. offline_sync_sdk-0.2.0/.github/workflows/database-adapters.yml +204 -0
  3. offline_sync_sdk-0.2.0/.github/workflows/pypi.yml +37 -0
  4. offline_sync_sdk-0.2.0/.github/workflows/testpypi.yml +33 -0
  5. offline_sync_sdk-0.2.0/CHANGELOG.md +33 -0
  6. offline_sync_sdk-0.2.0/CONTRIBUTING.md +63 -0
  7. offline_sync_sdk-0.2.0/LICENSE +21 -0
  8. offline_sync_sdk-0.2.0/PKG-INFO +447 -0
  9. offline_sync_sdk-0.2.0/README.md +384 -0
  10. offline_sync_sdk-0.2.0/SECURITY.md +23 -0
  11. offline_sync_sdk-0.2.0/TESTING.md +309 -0
  12. offline_sync_sdk-0.2.0/benchmarks/sync_throughput.py +321 -0
  13. offline_sync_sdk-0.2.0/docs/approach_architecture.md +297 -0
  14. offline_sync_sdk-0.2.0/docs/assets/backend-benchmark-comparison.svg +48 -0
  15. offline_sync_sdk-0.2.0/docs/assets/benchmark-summary.svg +42 -0
  16. offline_sync_sdk-0.2.0/docs/assets/postgresql-benchmark-summary.svg +39 -0
  17. offline_sync_sdk-0.2.0/docs/benchmarks.md +156 -0
  18. offline_sync_sdk-0.2.0/docs/mongodb.md +109 -0
  19. offline_sync_sdk-0.2.0/docs/observability.md +201 -0
  20. offline_sync_sdk-0.2.0/examples/pluggable_tasks.py +69 -0
  21. offline_sync_sdk-0.2.0/pyproject.toml +127 -0
  22. offline_sync_sdk-0.2.0/pyproject.toml.orig +112 -0
  23. offline_sync_sdk-0.2.0/src/sync_sdk/__init__.py +39 -0
  24. offline_sync_sdk-0.2.0/src/sync_sdk/adapters/__init__.py +1 -0
  25. offline_sync_sdk-0.2.0/src/sync_sdk/adapters/direct.py +15 -0
  26. offline_sync_sdk-0.2.0/src/sync_sdk/adapters/http.py +71 -0
  27. offline_sync_sdk-0.2.0/src/sync_sdk/adapters/mongodb.py +473 -0
  28. offline_sync_sdk-0.2.0/src/sync_sdk/adapters/opentelemetry.py +231 -0
  29. offline_sync_sdk-0.2.0/src/sync_sdk/adapters/sqlalchemy.py +691 -0
  30. offline_sync_sdk-0.2.0/src/sync_sdk/adapters/sqlalchemy_config.py +145 -0
  31. offline_sync_sdk-0.2.0/src/sync_sdk/client.py +198 -0
  32. offline_sync_sdk-0.2.0/src/sync_sdk/gateway.py +163 -0
  33. offline_sync_sdk-0.2.0/src/sync_sdk/integrations/__init__.py +1 -0
  34. offline_sync_sdk-0.2.0/src/sync_sdk/integrations/fastapi.py +32 -0
  35. offline_sync_sdk-0.2.0/src/sync_sdk/models.py +41 -0
  36. offline_sync_sdk-0.2.0/src/sync_sdk/ports.py +94 -0
  37. offline_sync_sdk-0.2.0/src/sync_sdk/py.typed +1 -0
  38. offline_sync_sdk-0.2.0/src/sync_sdk/registry.py +44 -0
  39. offline_sync_sdk-0.2.0/src/sync_sdk/store.py +147 -0
  40. offline_sync_sdk-0.2.0/src/sync_sdk/telemetry.py +131 -0
  41. offline_sync_sdk-0.2.0/tests/conftest.py +33 -0
  42. offline_sync_sdk-0.2.0/tests/contracts/test_adapters.py +321 -0
  43. offline_sync_sdk-0.2.0/tests/contracts/test_mongodb_configuration.py +93 -0
  44. offline_sync_sdk-0.2.0/tests/contracts/test_packaging_and_migration.py +138 -0
  45. offline_sync_sdk-0.2.0/tests/contracts/test_schema_configuration.py +260 -0
  46. offline_sync_sdk-0.2.0/tests/integration/test_mongodb_adapter.py +111 -0
  47. offline_sync_sdk-0.2.0/tests/integration/test_reliability.py +321 -0
  48. offline_sync_sdk-0.2.0/tests/integration/test_sql_database_adapters.py +197 -0
  49. offline_sync_sdk-0.2.0/tests/integration/test_sync_api.py +248 -0
  50. offline_sync_sdk-0.2.0/tests/test_observability.py +323 -0
@@ -0,0 +1,70 @@
1
+ name: CI
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [master]
7
+
8
+ permissions:
9
+ contents: read
10
+
11
+ jobs:
12
+ test:
13
+ runs-on: ubuntu-latest
14
+ strategy:
15
+ fail-fast: false
16
+ matrix:
17
+ python-version: ["3.12", "3.13", "3.14"]
18
+
19
+ steps:
20
+ - uses: actions/checkout@v7
21
+ - uses: astral-sh/setup-uv@v10.1.0
22
+ with:
23
+ version: "0.12.13"
24
+ python-version: ${{ matrix.python-version }}
25
+ enable-cache: true
26
+
27
+ - name: Install dependencies
28
+ run: uv sync --locked --group dev --all-extras
29
+
30
+ - name: Run tests
31
+ run: uv run pytest -q
32
+
33
+ - name: Run Ruff
34
+ if: matrix.python-version == '3.12'
35
+ run: uv run ruff check src tests benchmarks
36
+
37
+ - name: Run mypy
38
+ if: matrix.python-version == '3.12'
39
+ env:
40
+ MYPYPATH: src
41
+ run: uv run mypy src benchmarks/sync_throughput.py
42
+
43
+ package:
44
+ runs-on: ubuntu-latest
45
+ steps:
46
+ - uses: actions/checkout@v7
47
+ - uses: astral-sh/setup-uv@v10.1.0
48
+ with:
49
+ version: "0.12.13"
50
+ python-version: "3.12"
51
+ enable-cache: true
52
+
53
+ - name: Build distributions
54
+ run: uv build --no-sources
55
+
56
+ - name: Check package metadata
57
+ run: uvx --from twine twine check dist/*
58
+
59
+ - name: Install and import wheel
60
+ run: |
61
+ uv venv /tmp/sync-sdk-wheel-check
62
+ uv pip install --python /tmp/sync-sdk-wheel-check/bin/python dist/*.whl
63
+ /tmp/sync-sdk-wheel-check/bin/python -c \
64
+ 'import importlib.metadata as m; import sync_sdk; print(m.version("offline-sync-sdk"))'
65
+
66
+ - name: Save distributions
67
+ uses: actions/upload-artifact@v7
68
+ with:
69
+ name: python-distributions
70
+ path: dist/*
@@ -0,0 +1,204 @@
1
+ name: Database adapters
2
+
3
+ on:
4
+ pull_request:
5
+ push:
6
+ branches: [master]
7
+ workflow_dispatch:
8
+
9
+ permissions:
10
+ contents: read
11
+
12
+ jobs:
13
+ live-sql:
14
+ runs-on: ubuntu-latest
15
+ services:
16
+ postgres:
17
+ image: postgres:16-alpine
18
+ env:
19
+ POSTGRES_USER: sync
20
+ POSTGRES_PASSWORD: sync
21
+ POSTGRES_DB: sync_test
22
+ ports:
23
+ - 5432:5432
24
+ options: >-
25
+ --health-cmd "pg_isready -U sync -d sync_test"
26
+ --health-interval 5s
27
+ --health-timeout 5s
28
+ --health-retries 20
29
+ mysql:
30
+ image: mysql:8.4
31
+ env:
32
+ MYSQL_DATABASE: sync_test
33
+ MYSQL_USER: sync
34
+ MYSQL_PASSWORD: sync
35
+ MYSQL_ROOT_PASSWORD: root
36
+ ports:
37
+ - 3306:3306
38
+ options: >-
39
+ --health-cmd "mysqladmin ping -h 127.0.0.1 -uroot -proot"
40
+ --health-interval 5s
41
+ --health-timeout 5s
42
+ --health-retries 20
43
+
44
+ steps:
45
+ - uses: actions/checkout@v7
46
+ - uses: astral-sh/setup-uv@v10.1.0
47
+ with:
48
+ version: "0.12.13"
49
+ enable-cache: true
50
+
51
+ - name: Install test dependencies
52
+ run: uv sync --locked --group dev --extra postgres --extra mysql
53
+
54
+ - name: Test adapters and collect metrics
55
+ env:
56
+ SYNC_TEST_POSTGRES_URL: postgresql+asyncpg://sync:sync@127.0.0.1:5432/sync_test
57
+ SYNC_TEST_MYSQL_URL: mysql+asyncmy://sync:sync@127.0.0.1:3306/sync_test
58
+ SYNC_TEST_METRICS_PATH: database-adapter-metrics.json
59
+ run: >-
60
+ uv run pytest tests/integration/test_sql_database_adapters.py
61
+ -q -s --junitxml=database-adapter-tests.xml
62
+
63
+ - name: Benchmark PostgreSQL throughput
64
+ env:
65
+ SYNC_TEST_POSTGRES_URL: postgresql+asyncpg://sync:sync@127.0.0.1:5432/sync_test
66
+ run: |
67
+ set -euo pipefail
68
+ for concurrency in 1 2 4 8; do
69
+ uv run python benchmarks/sync_throughput.py \
70
+ --database-url "$SYNC_TEST_POSTGRES_URL" \
71
+ --mutations 1000 \
72
+ --warmup 100 \
73
+ --batch-size 100 \
74
+ --concurrency "$concurrency" \
75
+ --fail-on-errors \
76
+ --output "benchmark-postgresql-c${concurrency}.json"
77
+ done
78
+
79
+ - name: Benchmark MySQL throughput
80
+ env:
81
+ SYNC_TEST_MYSQL_URL: mysql+asyncmy://sync:sync@127.0.0.1:3306/sync_test
82
+ run: |
83
+ set -euo pipefail
84
+ for concurrency in 1 2 4 8; do
85
+ uv run python benchmarks/sync_throughput.py \
86
+ --database-url "$SYNC_TEST_MYSQL_URL" \
87
+ --mutations 1000 \
88
+ --warmup 100 \
89
+ --batch-size 100 \
90
+ --concurrency "$concurrency" \
91
+ --fail-on-errors \
92
+ --output "benchmark-mysql-c${concurrency}.json"
93
+ done
94
+
95
+ - name: Show metric report
96
+ if: always()
97
+ run: |
98
+ if test -f database-adapter-metrics.json; then
99
+ {
100
+ echo '## Database adapter metrics'
101
+ echo '```json'
102
+ cat database-adapter-metrics.json
103
+ echo '```'
104
+ } >> "$GITHUB_STEP_SUMMARY"
105
+ fi
106
+ for report in benchmark-*-c*.json; do
107
+ if test -f "$report"; then
108
+ {
109
+ echo "## $report"
110
+ echo '```json'
111
+ cat "$report"
112
+ echo '```'
113
+ } >> "$GITHUB_STEP_SUMMARY"
114
+ fi
115
+ done
116
+
117
+ - name: Save test reports
118
+ if: always()
119
+ uses: actions/upload-artifact@v7
120
+ with:
121
+ name: database-adapter-reports
122
+ path: |
123
+ database-adapter-metrics.json
124
+ database-adapter-tests.xml
125
+ benchmark-*-c*.json
126
+ if-no-files-found: ignore
127
+
128
+ live-mongodb:
129
+ runs-on: ubuntu-latest
130
+ steps:
131
+ - uses: actions/checkout@v7
132
+ - uses: astral-sh/setup-uv@v10.1.0
133
+ with:
134
+ version: "0.12.13"
135
+ enable-cache: true
136
+
137
+ - name: Start MongoDB replica set
138
+ run: |
139
+ docker run --detach --name sync-mongodb --publish 27017:27017 \
140
+ mongo:8.0 --replSet rs0 --bind_ip_all
141
+ for attempt in $(seq 1 60); do
142
+ docker exec sync-mongodb mongosh --quiet \
143
+ --eval 'db.adminCommand({ping: 1}).ok' >/dev/null 2>&1 && break
144
+ test "$attempt" -lt 60 || exit 1
145
+ sleep 1
146
+ done
147
+ docker exec sync-mongodb mongosh --quiet --eval \
148
+ 'rs.initiate({_id: "rs0", members: [{_id: 0, host: "localhost:27017"}]})'
149
+ for attempt in $(seq 1 60); do
150
+ docker exec sync-mongodb mongosh --quiet \
151
+ --eval 'db.hello().isWritablePrimary' | grep -q true && break
152
+ test "$attempt" -lt 60 || exit 1
153
+ sleep 1
154
+ done
155
+
156
+ - name: Install test dependencies
157
+ run: uv sync --locked --group dev --extra mongodb
158
+
159
+ - name: Test MongoDB adapter
160
+ env:
161
+ SYNC_TEST_MONGODB_URL: "mongodb://127.0.0.1:27017/sync_test?replicaSet=rs0&directConnection=true"
162
+ run: >-
163
+ uv run pytest tests/integration/test_mongodb_adapter.py
164
+ -q --junitxml=mongodb-adapter-tests.xml
165
+
166
+ - name: Benchmark MongoDB throughput
167
+ env:
168
+ SYNC_TEST_MONGODB_URL: "mongodb://127.0.0.1:27017/sync_test?replicaSet=rs0&directConnection=true"
169
+ run: |
170
+ set -euo pipefail
171
+ for concurrency in 1 2 4 8; do
172
+ uv run python benchmarks/sync_throughput.py \
173
+ --mongodb-url "$SYNC_TEST_MONGODB_URL" \
174
+ --mutations 1000 \
175
+ --warmup 100 \
176
+ --batch-size 100 \
177
+ --concurrency "$concurrency" \
178
+ --fail-on-errors \
179
+ --output "benchmark-mongodb-c${concurrency}.json"
180
+ done
181
+
182
+ - name: Show MongoDB benchmark reports
183
+ if: always()
184
+ run: |
185
+ for report in benchmark-mongodb-c*.json; do
186
+ if test -f "$report"; then
187
+ {
188
+ echo "## $report"
189
+ echo '```json'
190
+ cat "$report"
191
+ echo '```'
192
+ } >> "$GITHUB_STEP_SUMMARY"
193
+ fi
194
+ done
195
+
196
+ - name: Save MongoDB test report
197
+ if: always()
198
+ uses: actions/upload-artifact@v7
199
+ with:
200
+ name: mongodb-adapter-report
201
+ path: |
202
+ mongodb-adapter-tests.xml
203
+ benchmark-mongodb-c*.json
204
+ if-no-files-found: ignore
@@ -0,0 +1,37 @@
1
+ name: Publish to PyPI
2
+
3
+ on:
4
+ release:
5
+ types: [published]
6
+
7
+ permissions:
8
+ contents: read
9
+
10
+ jobs:
11
+ publish:
12
+ name: Build and publish
13
+ runs-on: ubuntu-latest
14
+ environment: pypi
15
+ permissions:
16
+ contents: read
17
+ id-token: write
18
+
19
+ steps:
20
+ - uses: actions/checkout@v7
21
+
22
+ - name: Install uv
23
+ uses: astral-sh/setup-uv@v10.1.0
24
+ with:
25
+ version: "0.12.13"
26
+ enable-cache: true
27
+
28
+ - name: Verify release tag
29
+ run: |
30
+ package_version="$(python -c 'import tomllib; print(tomllib.load(open("pyproject.toml", "rb"))["project"]["version"])')"
31
+ test "$GITHUB_REF_NAME" = "v$package_version"
32
+
33
+ - name: Build package
34
+ run: uv build --no-sources
35
+
36
+ - name: Publish package
37
+ uses: pypa/gh-action-pypi-publish@release/v1
@@ -0,0 +1,33 @@
1
+ name: Publish to TestPyPI
2
+
3
+ on:
4
+ workflow_dispatch:
5
+
6
+ permissions:
7
+ contents: read
8
+
9
+ jobs:
10
+ publish:
11
+ name: Build and publish
12
+ runs-on: ubuntu-latest
13
+ environment: testpypi
14
+ permissions:
15
+ contents: read
16
+ id-token: write
17
+
18
+ steps:
19
+ - uses: actions/checkout@v7
20
+
21
+ - name: Install uv
22
+ uses: astral-sh/setup-uv@v10.1.0
23
+ with:
24
+ version: "0.12.13"
25
+ enable-cache: true
26
+
27
+ - name: Build package
28
+ run: uv build --no-sources
29
+
30
+ - name: Publish package to TestPyPI
31
+ uses: pypa/gh-action-pypi-publish@release/v1
32
+ with:
33
+ repository-url: https://test.pypi.org/legacy/
@@ -0,0 +1,33 @@
1
+ # Changelog
2
+
3
+ Notable changes to Sync SDK are recorded here. The project follows semantic
4
+ versioning while allowing breaking API changes before version 1.0.
5
+
6
+ ## [Unreleased]
7
+
8
+ ## [0.2.0] - 2026-10-16
9
+
10
+ ### Added
11
+
12
+ - Transactional MongoDB adapter for replica sets and sharded clusters.
13
+ - Polling SQL change capture for writes made outside the gateway.
14
+ - Reproducible PostgreSQL, MySQL, MongoDB, and SQLite throughput benchmarks.
15
+ - Database concurrency benchmarks with correctness auditing in GitHub Actions.
16
+ - Benchmark results and concise comparison visuals.
17
+ - MIT licensing and a DCO-based contribution policy.
18
+
19
+ ### Changed
20
+
21
+ - Published under the `offline-sync-sdk` distribution name to avoid a production
22
+ PyPI name collision; the `sync_sdk` import package and `sync-sdk` command remain
23
+ unchanged.
24
+ - Documented PostgreSQL as the recommended production gateway database.
25
+ - Expanded database, packaging, observability, and deployment guidance.
26
+
27
+ ### Verified
28
+
29
+ - PostgreSQL 16, MySQL 8.4, and MongoDB 8.0 completed the concurrency 1, 2, 4,
30
+ and 8 benchmark matrix with zero failed mutations.
31
+ - The full local suite passed with 58 tests and 3 expected environment skips.
32
+
33
+ [Unreleased]: https://github.com/VivekReddy10-08-2004/sync-sdk/compare/v0.2.0...HEAD
@@ -0,0 +1,63 @@
1
+ # Contributing
2
+
3
+ Thank you for improving Sync SDK. Bug reports, documentation fixes, tests, and
4
+ focused code changes are welcome.
5
+
6
+ ## Before you start
7
+
8
+ - Search existing issues and pull requests before opening a duplicate.
9
+ - Open an issue before a large change so its behavior and scope can be agreed.
10
+ - Report security problems privately as described in [SECURITY.md](SECURITY.md).
11
+
12
+ ## Make a change
13
+
14
+ Sync SDK requires Python 3.12 or newer and uses `uv` for its development
15
+ environment.
16
+
17
+ ```sh
18
+ git clone https://github.com/VivekReddy10-08-2004/sync-sdk.git
19
+ cd sync-sdk
20
+ uv sync --locked --group dev --all-extras
21
+ uv run pytest -q
22
+ ```
23
+
24
+ Keep changes focused. Add tests when behavior changes, update the relevant
25
+ documentation, and avoid committing credentials, local databases, generated
26
+ environments, or benchmark results from an unrepeatable setup.
27
+
28
+ Before opening a pull request, run:
29
+
30
+ ```sh
31
+ uv run ruff check src tests benchmarks
32
+ MYPYPATH=src uv run mypy src benchmarks/sync_throughput.py
33
+ uv run pytest -q
34
+ ```
35
+
36
+ Database-specific changes should also pass the relevant live adapter contract.
37
+ The pull request workflow runs PostgreSQL, MySQL, and MongoDB services.
38
+
39
+ ## Commit certification and license
40
+
41
+ This project uses the [Developer Certificate of Origin 1.1](https://developercertificate.org/)
42
+ instead of a separate Contributor License Agreement. Add a `Signed-off-by` line
43
+ to every commit with:
44
+
45
+ ```sh
46
+ git commit --signoff
47
+ ```
48
+
49
+ The sign-off certifies that you wrote the contribution, have the right to submit
50
+ it, and understand that it is public. Use your real name and an email address you
51
+ control. If needed, add a sign-off to your latest commit with
52
+ `git commit --amend --signoff`.
53
+
54
+ Contributions are accepted under the repository's [MIT License](LICENSE), using
55
+ the same license for incoming contributions and outgoing releases. You retain
56
+ copyright in your contribution. This policy does not transfer your copyright or
57
+ give the project permission to relicense your work under incompatible terms.
58
+
59
+ ## Pull requests
60
+
61
+ Explain the problem and resulting behavior, link related issues, and include the
62
+ commands used for validation. Maintainers may ask for changes to keep the public
63
+ API, storage guarantees, and documentation consistent.
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 VivekReddy10-08-2004
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.