bondi 0.1.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 (76) hide show
  1. bondi-0.1.0/.gitignore +24 -0
  2. bondi-0.1.0/CHANGELOG.md +12 -0
  3. bondi-0.1.0/CITATION.cff +9 -0
  4. bondi-0.1.0/LICENSE +21 -0
  5. bondi-0.1.0/PKG-INFO +100 -0
  6. bondi-0.1.0/README.md +74 -0
  7. bondi-0.1.0/pyproject.toml +61 -0
  8. bondi-0.1.0/src/bondi/__init__.py +1 -0
  9. bondi-0.1.0/src/bondi/_sync.py +122 -0
  10. bondi-0.1.0/src/bondi/couchbase/__init__.py +8 -0
  11. bondi-0.1.0/src/bondi/couchbase/executor.py +376 -0
  12. bondi-0.1.0/src/bondi/couchbase/explain.py +223 -0
  13. bondi-0.1.0/src/bondi/couchbase/query.py +187 -0
  14. bondi-0.1.0/src/bondi/couchbase/sync_executor.py +109 -0
  15. bondi-0.1.0/src/bondi/estimation.py +42 -0
  16. bondi-0.1.0/src/bondi/execution.py +58 -0
  17. bondi-0.1.0/src/bondi/mongodb/__init__.py +28 -0
  18. bondi-0.1.0/src/bondi/mongodb/_serialization.py +98 -0
  19. bondi-0.1.0/src/bondi/mongodb/aggregate.py +135 -0
  20. bondi-0.1.0/src/bondi/mongodb/collection.py +47 -0
  21. bondi-0.1.0/src/bondi/mongodb/estimator.py +331 -0
  22. bondi-0.1.0/src/bondi/mongodb/executor.py +380 -0
  23. bondi-0.1.0/src/bondi/mongodb/explain.py +172 -0
  24. bondi-0.1.0/src/bondi/mongodb/generation.py +508 -0
  25. bondi-0.1.0/src/bondi/mongodb/generation_config.py +178 -0
  26. bondi-0.1.0/src/bondi/mongodb/pattern.py +199 -0
  27. bondi-0.1.0/src/bondi/mongodb/query.py +188 -0
  28. bondi-0.1.0/src/bondi/mongodb/sync_executor.py +126 -0
  29. bondi-0.1.0/src/bondi/query.py +35 -0
  30. bondi-0.1.0/src/bondi/schema.py +329 -0
  31. bondi-0.1.0/src/bondi/summary.py +45 -0
  32. bondi-0.1.0/src/bondi/workload.py +284 -0
  33. bondi-0.1.0/tests/fixtures/couchbase/README.md +19 -0
  34. bondi-0.1.0/tests/fixtures/couchbase/community_aggregation.json +138 -0
  35. bondi-0.1.0/tests/fixtures/couchbase/community_covering.json +115 -0
  36. bondi-0.1.0/tests/fixtures/couchbase/community_empty.json +112 -0
  37. bondi-0.1.0/tests/fixtures/couchbase/community_filtered.json +112 -0
  38. bondi-0.1.0/tests/fixtures/couchbase/community_scalar.json +73 -0
  39. bondi-0.1.0/tests/fixtures/couchbase/community_sorted.json +131 -0
  40. bondi-0.1.0/tests/fixtures/couchbase/enterprise_aggregation.json +406 -0
  41. bondi-0.1.0/tests/fixtures/couchbase/enterprise_covering.json +317 -0
  42. bondi-0.1.0/tests/fixtures/couchbase/enterprise_empty.json +322 -0
  43. bondi-0.1.0/tests/fixtures/couchbase/enterprise_filtered.json +336 -0
  44. bondi-0.1.0/tests/fixtures/couchbase/enterprise_scalar.json +189 -0
  45. bondi-0.1.0/tests/fixtures/couchbase/enterprise_sorted.json +413 -0
  46. bondi-0.1.0/tests/fixtures/explain/README.md +17 -0
  47. bondi-0.1.0/tests/fixtures/explain/aggregate_facet.json +140 -0
  48. bondi-0.1.0/tests/fixtures/explain/aggregate_group.json +155 -0
  49. bondi-0.1.0/tests/fixtures/explain/aggregate_lookup.json +91 -0
  50. bondi-0.1.0/tests/fixtures/explain/aggregate_sort.json +90 -0
  51. bondi-0.1.0/tests/fixtures/explain/find_collscan.json +75 -0
  52. bondi-0.1.0/tests/fixtures/explain/find_index.json +123 -0
  53. bondi-0.1.0/tests/test_couchbase_executor.py +322 -0
  54. bondi-0.1.0/tests/test_couchbase_executor_live.py +92 -0
  55. bondi-0.1.0/tests/test_couchbase_explain.py +208 -0
  56. bondi-0.1.0/tests/test_couchbase_optional.py +33 -0
  57. bondi-0.1.0/tests/test_couchbase_query.py +165 -0
  58. bondi-0.1.0/tests/test_executor.py +442 -0
  59. bondi-0.1.0/tests/test_executor_mongodb.py +70 -0
  60. bondi-0.1.0/tests/test_explain.py +176 -0
  61. bondi-0.1.0/tests/test_mongo_generation.py +498 -0
  62. bondi-0.1.0/tests/test_mongo_generation_live.py +80 -0
  63. bondi-0.1.0/tests/test_mongodb_aggregate.py +174 -0
  64. bondi-0.1.0/tests/test_mongodb_collection.py +46 -0
  65. bondi-0.1.0/tests/test_mongodb_estimator.py +265 -0
  66. bondi-0.1.0/tests/test_mongodb_estimator_live.py +65 -0
  67. bondi-0.1.0/tests/test_mongodb_query.py +101 -0
  68. bondi-0.1.0/tests/test_mongodb_serialization.py +219 -0
  69. bondi-0.1.0/tests/test_package.py +13 -0
  70. bondi-0.1.0/tests/test_schema.py +207 -0
  71. bondi-0.1.0/tests/test_summarize.py +35 -0
  72. bondi-0.1.0/tests/test_sync_executors.py +216 -0
  73. bondi-0.1.0/tests/test_sync_notebook_live.py +88 -0
  74. bondi-0.1.0/tests/test_workload.py +135 -0
  75. bondi-0.1.0/tests/test_workload_persistence.py +149 -0
  76. bondi-0.1.0/uv.lock +949 -0
bondi-0.1.0/.gitignore ADDED
@@ -0,0 +1,24 @@
1
+ # Python and local environments
2
+ .venv/
3
+ __pycache__/
4
+ *.py[cod]
5
+ *.egg-info/
6
+ .pytest_cache/
7
+ .ruff_cache/
8
+ .coverage
9
+ htmlcov/
10
+
11
+ # Generated documentation and distributions
12
+ site/
13
+ dist/
14
+ build/
15
+
16
+ # Local configuration and notebook state
17
+ .env
18
+ .env.*
19
+ !.env.example
20
+ .ipynb_checkpoints/
21
+ .DS_Store
22
+
23
+ # Locally generated research workloads
24
+ /*workload*.jsonl
@@ -0,0 +1,12 @@
1
+ # Changelog
2
+
3
+ ## 0.1.0 — initial release (prepared)
4
+
5
+ - Native MongoDB find/aggregation and Couchbase SQL++ queries with JSONL workloads.
6
+ - Synchronous and asynchronous execution, explain and profile operations.
7
+ - Offline query summaries, schema inspection and optional value retention.
8
+ - MongoDB sampling estimation and pattern-based workload generation.
9
+ - Student notebooks, local Docker environments and documentation.
10
+
11
+ This is an early research release. Public APIs and persistence formats may change
12
+ in subsequent releases; retain the package version alongside experiment artifacts.
@@ -0,0 +1,9 @@
1
+ cff-version: 1.2.0
2
+ message: "If you use BONDI in research, please cite this software."
3
+ title: "BONDI: A Python toolkit for document database research"
4
+ authors:
5
+ - name: Relaxed Constraints
6
+ version: 0.1.0
7
+ license: MIT
8
+ repository-code: "https://github.com/relaxed-constraints/bondi"
9
+ url: "https://relaxed-constraints.github.io/bondi/"
bondi-0.1.0/LICENSE ADDED
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 Relaxed Constraints
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.
bondi-0.1.0/PKG-INFO ADDED
@@ -0,0 +1,100 @@
1
+ Metadata-Version: 2.5
2
+ Name: bondi
3
+ Version: 0.1.0
4
+ Summary: A Python toolkit for document database research
5
+ Project-URL: Homepage, https://github.com/relaxed-constraints/bondi
6
+ Project-URL: Documentation, https://relaxed-constraints.github.io/bondi/
7
+ Project-URL: Repository, https://github.com/relaxed-constraints/bondi
8
+ Project-URL: Issues, https://github.com/relaxed-constraints/bondi/issues
9
+ Project-URL: Changelog, https://github.com/relaxed-constraints/bondi/blob/main/CHANGELOG.md
10
+ Author: Relaxed Constraints
11
+ License-Expression: MIT
12
+ License-File: LICENSE
13
+ Classifier: Development Status :: 3 - Alpha
14
+ Classifier: Intended Audience :: Science/Research
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.11
17
+ Classifier: Programming Language :: Python :: 3.12
18
+ Classifier: Programming Language :: Python :: 3.13
19
+ Classifier: Programming Language :: Python :: 3.14
20
+ Classifier: Topic :: Database
21
+ Requires-Python: >=3.11
22
+ Requires-Dist: pymongo<5,>=4.13
23
+ Provides-Extra: couchbase
24
+ Requires-Dist: couchbase<5,>=4.6.3; extra == 'couchbase'
25
+ Description-Content-Type: text/markdown
26
+
27
+ # BONDI — A Python toolkit for document database research
28
+
29
+ **bondi** provides A Python toolkit for document database research.
30
+
31
+ Use native MongoDB and Couchbase queries, execute and profile workloads, inspect
32
+ schemas, estimate MongoDB selectivity, and generate pattern-based workloads.
33
+ Synchronous APIs work in scripts and notebooks; async APIs remain available.
34
+ Research algorithms and experiment tracking stay in separate projects.
35
+
36
+ Start with [installation](docs/installation.md) and the [quickstart](docs/quickstart.md),
37
+ or browse the [documentation overview](docs/index.md).
38
+
39
+ ## Start developing
40
+
41
+ Requires [uv](https://docs.astral.sh/uv/) and Python 3.11 or newer. From this directory:
42
+
43
+ ```sh
44
+ uv sync --locked
45
+ uv run python -c "import bondi; print(bondi.__file__)"
46
+ uv run pytest
47
+ uv run ruff check .
48
+ uv run ruff format --check .
49
+ ```
50
+
51
+ `uv sync` installs the package in editable mode and includes the development group.
52
+ PyMongo is a required dependency for BSON support; no database service is needed.
53
+ The committed `uv.lock` records the development dependency resolution.
54
+
55
+ [Documentation](https://relaxed-constraints.github.io/bondi/) ·
56
+ [Issues](https://github.com/relaxed-constraints/bondi/issues) · [MIT license](LICENSE)
57
+
58
+ ## Read the documentation
59
+
60
+ Start with [the documentation overview](docs/index.md),
61
+ [architecture decisions](docs/architecture.md), and
62
+ [the implementation roadmap](docs/roadmap.md).
63
+
64
+ To preview or validate the documentation site:
65
+
66
+ ```sh
67
+ uv sync --locked --group docs
68
+ uv run --group docs mkdocs serve
69
+ # Or build without starting a server:
70
+ uv run --group docs mkdocs build --strict
71
+ ```
72
+
73
+ API reference pages are generated from Python docstrings using mkdocstrings.
74
+ Tutorials are available in `notebooks/workload_demo.ipynb` (MongoDB) and
75
+ `notebooks/couchbase_demo.ipynb` (Couchbase).
76
+ For database-independent inference and inspection, see the [schema guide](docs/schemas.md)
77
+ and `notebooks/schema_demo.ipynb`.
78
+
79
+ ## Repository layout
80
+
81
+ ```text
82
+ src/bondi/ Installable library
83
+ tests/ Offline tests
84
+ docs/ Getting started, guides, tutorials, API reference and development
85
+ ```
86
+
87
+ See [the contributor guide](docs/contributing.md) for the development workflow.
88
+ A distribution can be built with `uv build`.
89
+
90
+ ## Publication
91
+
92
+ BONDI is MIT licensed, copyright Relaxed Constraints. Version 0.1.0 is being
93
+ prepared for PyPI; use the source installation instructions until it is published.
94
+ See [release preparation](docs/releases.md) for the publishing process.
95
+
96
+ ## Optional local databases
97
+
98
+ See [the local database guide](docs/local-databases.md) for MongoDB and Couchbase
99
+ Docker Compose profiles, sample data, startup and cleanup. No database or Docker
100
+ installation is required for the offline test suite.
bondi-0.1.0/README.md ADDED
@@ -0,0 +1,74 @@
1
+ # BONDI — A Python toolkit for document database research
2
+
3
+ **bondi** provides A Python toolkit for document database research.
4
+
5
+ Use native MongoDB and Couchbase queries, execute and profile workloads, inspect
6
+ schemas, estimate MongoDB selectivity, and generate pattern-based workloads.
7
+ Synchronous APIs work in scripts and notebooks; async APIs remain available.
8
+ Research algorithms and experiment tracking stay in separate projects.
9
+
10
+ Start with [installation](docs/installation.md) and the [quickstart](docs/quickstart.md),
11
+ or browse the [documentation overview](docs/index.md).
12
+
13
+ ## Start developing
14
+
15
+ Requires [uv](https://docs.astral.sh/uv/) and Python 3.11 or newer. From this directory:
16
+
17
+ ```sh
18
+ uv sync --locked
19
+ uv run python -c "import bondi; print(bondi.__file__)"
20
+ uv run pytest
21
+ uv run ruff check .
22
+ uv run ruff format --check .
23
+ ```
24
+
25
+ `uv sync` installs the package in editable mode and includes the development group.
26
+ PyMongo is a required dependency for BSON support; no database service is needed.
27
+ The committed `uv.lock` records the development dependency resolution.
28
+
29
+ [Documentation](https://relaxed-constraints.github.io/bondi/) ·
30
+ [Issues](https://github.com/relaxed-constraints/bondi/issues) · [MIT license](LICENSE)
31
+
32
+ ## Read the documentation
33
+
34
+ Start with [the documentation overview](docs/index.md),
35
+ [architecture decisions](docs/architecture.md), and
36
+ [the implementation roadmap](docs/roadmap.md).
37
+
38
+ To preview or validate the documentation site:
39
+
40
+ ```sh
41
+ uv sync --locked --group docs
42
+ uv run --group docs mkdocs serve
43
+ # Or build without starting a server:
44
+ uv run --group docs mkdocs build --strict
45
+ ```
46
+
47
+ API reference pages are generated from Python docstrings using mkdocstrings.
48
+ Tutorials are available in `notebooks/workload_demo.ipynb` (MongoDB) and
49
+ `notebooks/couchbase_demo.ipynb` (Couchbase).
50
+ For database-independent inference and inspection, see the [schema guide](docs/schemas.md)
51
+ and `notebooks/schema_demo.ipynb`.
52
+
53
+ ## Repository layout
54
+
55
+ ```text
56
+ src/bondi/ Installable library
57
+ tests/ Offline tests
58
+ docs/ Getting started, guides, tutorials, API reference and development
59
+ ```
60
+
61
+ See [the contributor guide](docs/contributing.md) for the development workflow.
62
+ A distribution can be built with `uv build`.
63
+
64
+ ## Publication
65
+
66
+ BONDI is MIT licensed, copyright Relaxed Constraints. Version 0.1.0 is being
67
+ prepared for PyPI; use the source installation instructions until it is published.
68
+ See [release preparation](docs/releases.md) for the publishing process.
69
+
70
+ ## Optional local databases
71
+
72
+ See [the local database guide](docs/local-databases.md) for MongoDB and Couchbase
73
+ Docker Compose profiles, sample data, startup and cleanup. No database or Docker
74
+ installation is required for the offline test suite.
@@ -0,0 +1,61 @@
1
+ [project]
2
+ name = "bondi"
3
+ version = "0.1.0"
4
+ description = "A Python toolkit for document database research"
5
+ readme = "README.md"
6
+ license = "MIT"
7
+ license-files = ["LICENSE"]
8
+ authors = [{name = "Relaxed Constraints"}]
9
+ classifiers = [
10
+ "Development Status :: 3 - Alpha",
11
+ "Intended Audience :: Science/Research",
12
+ "Programming Language :: Python :: 3",
13
+ "Programming Language :: Python :: 3.11",
14
+ "Programming Language :: Python :: 3.12",
15
+ "Programming Language :: Python :: 3.13",
16
+ "Programming Language :: Python :: 3.14",
17
+ "Topic :: Database",
18
+ ]
19
+ requires-python = ">=3.11"
20
+ dependencies = [
21
+ "pymongo>=4.13,<5",
22
+ ]
23
+
24
+ [project.urls]
25
+ Homepage = "https://github.com/relaxed-constraints/bondi"
26
+ Documentation = "https://relaxed-constraints.github.io/bondi/"
27
+ Repository = "https://github.com/relaxed-constraints/bondi"
28
+ Issues = "https://github.com/relaxed-constraints/bondi/issues"
29
+ Changelog = "https://github.com/relaxed-constraints/bondi/blob/main/CHANGELOG.md"
30
+
31
+ [project.optional-dependencies]
32
+ couchbase = ["couchbase>=4.6.3,<5"]
33
+
34
+ [build-system]
35
+ requires = ["hatchling>=1.26"]
36
+ build-backend = "hatchling.build"
37
+
38
+ [dependency-groups]
39
+ dev = ["pytest>=8", "ruff>=0.9"]
40
+ docs = [
41
+ "mkdocs>=1.6,<2",
42
+ "mkdocs-material>=9.6,<10",
43
+ "mkdocstrings[python]>=0.28",
44
+ ]
45
+
46
+ [tool.hatch.build.targets.wheel]
47
+ packages = ["src/bondi"]
48
+
49
+ [tool.pytest.ini_options]
50
+ testpaths = ["tests", "src/bondi"]
51
+ addopts = "--import-mode=importlib --doctest-modules"
52
+
53
+ [tool.ruff]
54
+ line-length = 100
55
+ target-version = "py311"
56
+
57
+ [tool.ruff.lint]
58
+ select = ["E", "F", "I", "UP"]
59
+
60
+ [tool.hatch.build.targets.sdist]
61
+ include = ["/src", "/tests", "/pyproject.toml", "/uv.lock", "/README.md", "/LICENSE", "/CHANGELOG.md", "/CITATION.cff"]
@@ -0,0 +1 @@
1
+ """A Python toolkit for document database research."""
@@ -0,0 +1,122 @@
1
+ """Private background-loop bridge for synchronous database facades."""
2
+
3
+ import asyncio
4
+ from concurrent.futures import Future
5
+ from threading import Event, Thread, get_ident
6
+ from typing import Self
7
+
8
+
9
+ class _SyncExecutor:
10
+ """Own an async executor on a background loop; calls stay on the owner thread."""
11
+
12
+ def __init__(self):
13
+ raise TypeError("Use from_uri() to create an owned executor")
14
+
15
+ @classmethod
16
+ def _create(cls, factory):
17
+ self = object.__new__(cls)
18
+ self._thread = get_ident()
19
+ self._closed = False
20
+ self._executor = None
21
+ ready = Event()
22
+
23
+ def serve():
24
+ with asyncio.Runner() as runner:
25
+ self._loop = runner.get_loop()
26
+ ready.set()
27
+ self._loop.run_forever()
28
+
29
+ self._worker = Thread(target=serve, name=f"bondi-{cls.__name__}", daemon=True)
30
+ self._worker.start()
31
+ ready.wait()
32
+
33
+ async def connect():
34
+ self._executor = await factory()
35
+
36
+ try:
37
+ self._submit(connect)
38
+ except BaseException:
39
+ try:
40
+ if self._executor is not None:
41
+ self._submit(self._executor.close, cancel_on_interrupt=False)
42
+ finally:
43
+ self._shutdown()
44
+ raise
45
+ return self
46
+
47
+ def _check(self):
48
+ if get_ident() != self._thread:
49
+ raise RuntimeError("Use this executor only from its creating thread")
50
+ if self._closed:
51
+ raise RuntimeError("Executor is closed")
52
+
53
+ def _submit(self, operation, *, cancel_on_interrupt=True):
54
+ """Wait for an operation, including its cancellation cleanup on interrupt."""
55
+ self._check()
56
+ outcome = Future()
57
+ task = None
58
+
59
+ async def invoke():
60
+ try:
61
+ value = await operation()
62
+ except BaseException as error:
63
+ outcome.set_exception(error)
64
+ else:
65
+ outcome.set_result(value)
66
+
67
+ def start():
68
+ nonlocal task
69
+ task = self._loop.create_task(invoke())
70
+
71
+ def cancel():
72
+ if task is not None and not task.done():
73
+ # Schedule after the already-queued first task step.
74
+ self._loop.call_soon(task.cancel)
75
+
76
+ self._loop.call_soon_threadsafe(start)
77
+ try:
78
+ return outcome.result()
79
+ except KeyboardInterrupt:
80
+ if cancel_on_interrupt:
81
+ self._loop.call_soon_threadsafe(cancel)
82
+ # Do not return control until the coroutine has finished unwinding.
83
+ while not outcome.done():
84
+ try:
85
+ outcome.result(timeout=0.1)
86
+ except (KeyboardInterrupt, TimeoutError):
87
+ continue
88
+ except BaseException:
89
+ break
90
+ raise
91
+
92
+ def _call(self, method, *args, **kwargs):
93
+ async def invoke():
94
+ return await getattr(self._executor, method)(*args, **kwargs)
95
+
96
+ return self._submit(invoke)
97
+
98
+ def _shutdown(self):
99
+ self._closed = True
100
+ self._loop.call_soon_threadsafe(self._loop.stop)
101
+ while self._worker.is_alive():
102
+ try:
103
+ self._worker.join(timeout=0.1)
104
+ except KeyboardInterrupt:
105
+ continue
106
+
107
+ def close(self) -> None:
108
+ """Close the connection, stop its loop and join its thread; idempotent."""
109
+ if self._closed:
110
+ return
111
+ self._check()
112
+ try:
113
+ self._submit(self._executor.close, cancel_on_interrupt=False)
114
+ finally:
115
+ self._shutdown()
116
+
117
+ def __enter__(self) -> Self:
118
+ self._check()
119
+ return self
120
+
121
+ def __exit__(self, exc_type, exc, traceback) -> None:
122
+ self.close()
@@ -0,0 +1,8 @@
1
+ """Native Couchbase query descriptions without an SDK connection."""
2
+
3
+ from bondi.couchbase.executor import AsyncCouchbaseExecutor
4
+ from bondi.couchbase.explain import summarize
5
+ from bondi.couchbase.query import CouchbaseQuery
6
+ from bondi.couchbase.sync_executor import CouchbaseExecutor
7
+
8
+ __all__ = ["CouchbaseExecutor", "CouchbaseQuery", "AsyncCouchbaseExecutor", "summarize"]