datahike-browser-tests 1.0.0
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.
- package/.circleci/config.yml +405 -0
- package/.circleci/scripts/gen_ci.clj +194 -0
- package/.cirrus.yml +60 -0
- package/.clj-kondo/babashka/sci/config.edn +1 -0
- package/.clj-kondo/babashka/sci/sci/core.clj +9 -0
- package/.clj-kondo/config.edn +95 -0
- package/.dir-locals.el +2 -0
- package/.github/FUNDING.yml +3 -0
- package/.github/ISSUE_TEMPLATE/1-bug-report.yml +68 -0
- package/.github/ISSUE_TEMPLATE/2-feature-request.yml +28 -0
- package/.github/ISSUE_TEMPLATE/config.yml +6 -0
- package/.github/pull_request_template.md +24 -0
- package/.github/workflows/native-image.yml +84 -0
- package/LICENSE +203 -0
- package/README.md +273 -0
- package/bb/deps.edn +9 -0
- package/bb/resources/github-fingerprints +3 -0
- package/bb/resources/native-image-tests/run-bb-pod-tests.clj +162 -0
- package/bb/resources/native-image-tests/run-libdatahike-tests +12 -0
- package/bb/resources/native-image-tests/run-native-image-tests +74 -0
- package/bb/resources/native-image-tests/run-python-tests +22 -0
- package/bb/resources/native-image-tests/testconfig.attr-refs.edn +6 -0
- package/bb/resources/native-image-tests/testconfig.edn +5 -0
- package/bb/resources/template/.settings/org.eclipse.jdt.apt.core.prefs +2 -0
- package/bb/resources/template/.settings/org.eclipse.jdt.core.prefs +9 -0
- package/bb/resources/template/.settings/org.eclipse.m2e.core.prefs +4 -0
- package/bb/resources/template/pom.xml +22 -0
- package/bb/src/tools/build.clj +132 -0
- package/bb/src/tools/clj_kondo.clj +32 -0
- package/bb/src/tools/deploy.clj +26 -0
- package/bb/src/tools/examples.clj +19 -0
- package/bb/src/tools/npm.clj +100 -0
- package/bb/src/tools/python.clj +14 -0
- package/bb/src/tools/release.clj +94 -0
- package/bb/src/tools/test.clj +148 -0
- package/bb/src/tools/version.clj +47 -0
- package/bb.edn +269 -0
- package/benchmark/src/benchmark/cli.clj +195 -0
- package/benchmark/src/benchmark/compare.clj +157 -0
- package/benchmark/src/benchmark/config.clj +316 -0
- package/benchmark/src/benchmark/measure.clj +187 -0
- package/benchmark/src/benchmark/store.clj +190 -0
- package/benchmark/test/benchmark/measure_test.clj +156 -0
- package/build.clj +30 -0
- package/config.edn +49 -0
- package/deps.edn +138 -0
- package/dev/sandbox.clj +82 -0
- package/dev/sandbox.cljs +127 -0
- package/dev/sandbox_benchmarks.clj +27 -0
- package/dev/sandbox_client.clj +87 -0
- package/dev/sandbox_transact_bench.clj +109 -0
- package/dev/user.clj +79 -0
- package/doc/README.md +96 -0
- package/doc/adl/README.md +6 -0
- package/doc/adl/adr-000-adr.org +28 -0
- package/doc/adl/adr-001-attribute-references.org +15 -0
- package/doc/adl/adr-002-build-tooling.org +54 -0
- package/doc/adl/adr-003-db-meta-data.md +52 -0
- package/doc/adl/adr-004-github-flow.md +40 -0
- package/doc/adl/adr-XYZ-template.md +30 -0
- package/doc/adl/index.org +3 -0
- package/doc/assets/datahike-logo.svg +3 -0
- package/doc/assets/datahiking-invoice.org +85 -0
- package/doc/assets/hhtree2.png +0 -0
- package/doc/assets/network_topology.svg +624 -0
- package/doc/assets/perf.png +0 -0
- package/doc/assets/schema_mindmap.mm +132 -0
- package/doc/assets/schema_mindmap.svg +970 -0
- package/doc/assets/temporal_index.mm +74 -0
- package/doc/backend-development.md +78 -0
- package/doc/bb-pod.md +89 -0
- package/doc/benchmarking.md +360 -0
- package/doc/bindings/edn-conversion.md +383 -0
- package/doc/cli.md +162 -0
- package/doc/cljdoc.edn +27 -0
- package/doc/cljs-support.md +133 -0
- package/doc/config.md +406 -0
- package/doc/contributing.md +114 -0
- package/doc/datalog-vs-sql.md +210 -0
- package/doc/datomic_differences.md +109 -0
- package/doc/development/pull-api-ns.md +186 -0
- package/doc/development/pull-frame-state-diagram.jpg +0 -0
- package/doc/distributed.md +566 -0
- package/doc/entity_spec.md +92 -0
- package/doc/gc.md +273 -0
- package/doc/java-api.md +808 -0
- package/doc/javascript-api.md +421 -0
- package/doc/libdatahike.md +86 -0
- package/doc/logging_and_error_handling.md +43 -0
- package/doc/norms.md +66 -0
- package/doc/schema-migration.md +85 -0
- package/doc/schema.md +287 -0
- package/doc/storage-backends.md +363 -0
- package/doc/store-id-refactoring.md +596 -0
- package/doc/time_variance.md +325 -0
- package/doc/unstructured.md +167 -0
- package/doc/versioning.md +261 -0
- package/examples/basic/README.md +19 -0
- package/examples/basic/deps.edn +6 -0
- package/examples/basic/docker-compose.yml +13 -0
- package/examples/basic/src/examples/core.clj +60 -0
- package/examples/basic/src/examples/schema.clj +155 -0
- package/examples/basic/src/examples/store.clj +60 -0
- package/examples/basic/src/examples/time_travel.clj +185 -0
- package/examples/java/.settings/org.eclipse.core.resources.prefs +3 -0
- package/examples/java/.settings/org.eclipse.jdt.apt.core.prefs +2 -0
- package/examples/java/.settings/org.eclipse.jdt.core.prefs +9 -0
- package/examples/java/.settings/org.eclipse.m2e.core.prefs +4 -0
- package/examples/java/README.md +162 -0
- package/examples/java/pom.xml +62 -0
- package/examples/java/src/main/java/examples/QuickStart.java +115 -0
- package/examples/java/src/main/java/examples/SchemaExample.java +148 -0
- package/examples/java/src/main/java/examples/TimeTravelExample.java +121 -0
- package/flake.lock +27 -0
- package/flake.nix +27 -0
- package/http-server/datahike/http/middleware.clj +75 -0
- package/http-server/datahike/http/server.clj +269 -0
- package/java/src/datahike/java/Database.java +274 -0
- package/java/src/datahike/java/Datahike.java +281 -0
- package/java/src/datahike/java/DatahikeGeneratedTest.java +349 -0
- package/java/src/datahike/java/DatahikeTest.java +370 -0
- package/java/src/datahike/java/EDN.java +170 -0
- package/java/src/datahike/java/IEntity.java +11 -0
- package/java/src/datahike/java/Keywords.java +161 -0
- package/java/src/datahike/java/SchemaFlexibility.java +52 -0
- package/java/src/datahike/java/Util.java +219 -0
- package/karma.conf.js +19 -0
- package/libdatahike/compile-cpp +7 -0
- package/libdatahike/src/datahike/impl/LibDatahikeBase.java +203 -0
- package/libdatahike/src/datahike/impl/libdatahike.clj +59 -0
- package/libdatahike/src/test_cpp.cpp +61 -0
- package/npm-package/PUBLISHING.md +140 -0
- package/npm-package/README.md +226 -0
- package/npm-package/package.template.json +34 -0
- package/npm-package/test-isomorphic.ts +281 -0
- package/npm-package/test.js +557 -0
- package/npm-package/typescript-test.ts +70 -0
- package/package.json +16 -0
- package/pydatahike/README.md +569 -0
- package/pydatahike/pyproject.toml +91 -0
- package/pydatahike/setup.py +42 -0
- package/pydatahike/src/datahike/__init__.py +134 -0
- package/pydatahike/src/datahike/_native.py +250 -0
- package/pydatahike/src/datahike/_version.py +2 -0
- package/pydatahike/src/datahike/database.py +722 -0
- package/pydatahike/src/datahike/edn.py +311 -0
- package/pydatahike/src/datahike/py.typed +0 -0
- package/pydatahike/tests/conftest.py +17 -0
- package/pydatahike/tests/test_basic.py +170 -0
- package/pydatahike/tests/test_database.py +51 -0
- package/pydatahike/tests/test_edn_conversion.py +299 -0
- package/pydatahike/tests/test_query.py +99 -0
- package/pydatahike/tests/test_schema.py +55 -0
- package/resources/clj-kondo.exports/io.replikativ/datahike/config.edn +5 -0
- package/resources/example_server.edn +4 -0
- package/shadow-cljs.edn +56 -0
- package/src/data_readers.clj +7 -0
- package/src/datahike/api/impl.cljc +176 -0
- package/src/datahike/api/specification.cljc +633 -0
- package/src/datahike/api/types.cljc +261 -0
- package/src/datahike/api.cljc +41 -0
- package/src/datahike/array.cljc +99 -0
- package/src/datahike/cli.clj +166 -0
- package/src/datahike/cljs.cljs +6 -0
- package/src/datahike/codegen/cli.clj +406 -0
- package/src/datahike/codegen/clj_kondo.clj +291 -0
- package/src/datahike/codegen/java.clj +403 -0
- package/src/datahike/codegen/naming.cljc +33 -0
- package/src/datahike/codegen/native.clj +559 -0
- package/src/datahike/codegen/pod.clj +488 -0
- package/src/datahike/codegen/python.clj +838 -0
- package/src/datahike/codegen/report.clj +55 -0
- package/src/datahike/codegen/typescript.clj +262 -0
- package/src/datahike/codegen/validation.clj +145 -0
- package/src/datahike/config.cljc +294 -0
- package/src/datahike/connections.cljc +16 -0
- package/src/datahike/connector.cljc +265 -0
- package/src/datahike/constants.cljc +142 -0
- package/src/datahike/core.cljc +297 -0
- package/src/datahike/datom.cljc +459 -0
- package/src/datahike/db/interface.cljc +119 -0
- package/src/datahike/db/search.cljc +305 -0
- package/src/datahike/db/transaction.cljc +937 -0
- package/src/datahike/db/utils.cljc +338 -0
- package/src/datahike/db.cljc +956 -0
- package/src/datahike/experimental/unstructured.cljc +126 -0
- package/src/datahike/experimental/versioning.cljc +172 -0
- package/src/datahike/externs.js +31 -0
- package/src/datahike/gc.cljc +69 -0
- package/src/datahike/http/client.clj +188 -0
- package/src/datahike/http/writer.clj +79 -0
- package/src/datahike/impl/entity.cljc +218 -0
- package/src/datahike/index/interface.cljc +93 -0
- package/src/datahike/index/persistent_set.cljc +469 -0
- package/src/datahike/index/utils.cljc +44 -0
- package/src/datahike/index.cljc +32 -0
- package/src/datahike/js/api.cljs +172 -0
- package/src/datahike/js/api_macros.clj +22 -0
- package/src/datahike/js.cljs +163 -0
- package/src/datahike/json.cljc +209 -0
- package/src/datahike/lru.cljc +146 -0
- package/src/datahike/migrate.clj +39 -0
- package/src/datahike/norm/norm.clj +245 -0
- package/src/datahike/online_gc.cljc +252 -0
- package/src/datahike/pod.clj +155 -0
- package/src/datahike/pull_api.cljc +325 -0
- package/src/datahike/query.cljc +1945 -0
- package/src/datahike/query_stats.cljc +88 -0
- package/src/datahike/readers.cljc +62 -0
- package/src/datahike/remote.cljc +218 -0
- package/src/datahike/schema.cljc +228 -0
- package/src/datahike/schema_cache.cljc +42 -0
- package/src/datahike/spec.cljc +101 -0
- package/src/datahike/store.cljc +80 -0
- package/src/datahike/tools.cljc +308 -0
- package/src/datahike/transit.cljc +80 -0
- package/src/datahike/writer.cljc +239 -0
- package/src/datahike/writing.cljc +362 -0
- package/src/deps.cljs +1 -0
- package/src-hitchhiker-tree/datahike/index/hitchhiker_tree/insert.cljc +76 -0
- package/src-hitchhiker-tree/datahike/index/hitchhiker_tree/upsert.cljc +128 -0
- package/src-hitchhiker-tree/datahike/index/hitchhiker_tree.cljc +213 -0
- package/test/datahike/backward_compatibility_test/src/backward_test.clj +37 -0
- package/test/datahike/integration_test/config_record_file_test.clj +14 -0
- package/test/datahike/integration_test/config_record_test.clj +14 -0
- package/test/datahike/integration_test/depr_config_uri_test.clj +15 -0
- package/test/datahike/integration_test/return_map_test.clj +62 -0
- package/test/datahike/integration_test.cljc +67 -0
- package/test/datahike/norm/norm_test.clj +124 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/003-tx-fn-test.edn +1 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/004-tx-data-and-tx-fn-test.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/01-transact-basic-characters.edn +2 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/02 add occupation.edn +5 -0
- package/test/datahike/norm/resources/naming-and-sorting-test/checksums.edn +12 -0
- package/test/datahike/norm/resources/simple-test/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/simple-test/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/simple-test/checksums.edn +4 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/003-tx-fn-test.edn +1 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/first/checksums.edn +6 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/second/004-tx-data-and-tx-fn-test.edn +5 -0
- package/test/datahike/norm/resources/tx-data-and-tx-fn-test/second/checksums.edn +2 -0
- package/test/datahike/norm/resources/tx-fn-test/first/001-a1-example.edn +5 -0
- package/test/datahike/norm/resources/tx-fn-test/first/002-a2-example.edn +5 -0
- package/test/datahike/norm/resources/tx-fn-test/first/checksums.edn +4 -0
- package/test/datahike/norm/resources/tx-fn-test/second/003-tx-fn-test.edn +1 -0
- package/test/datahike/norm/resources/tx-fn-test/second/checksums.edn +2 -0
- package/test/datahike/test/api_test.cljc +895 -0
- package/test/datahike/test/array_test.cljc +40 -0
- package/test/datahike/test/attribute_refs/datoms_test.cljc +140 -0
- package/test/datahike/test/attribute_refs/db_test.cljc +42 -0
- package/test/datahike/test/attribute_refs/differences_test.cljc +515 -0
- package/test/datahike/test/attribute_refs/entity_test.cljc +89 -0
- package/test/datahike/test/attribute_refs/pull_api_test.cljc +320 -0
- package/test/datahike/test/attribute_refs/query_find_specs_test.cljc +59 -0
- package/test/datahike/test/attribute_refs/query_fns_test.cljc +130 -0
- package/test/datahike/test/attribute_refs/query_interop_test.cljc +47 -0
- package/test/datahike/test/attribute_refs/query_not_test.cljc +193 -0
- package/test/datahike/test/attribute_refs/query_or_test.cljc +137 -0
- package/test/datahike/test/attribute_refs/query_pull_test.cljc +156 -0
- package/test/datahike/test/attribute_refs/query_rules_test.cljc +176 -0
- package/test/datahike/test/attribute_refs/query_test.cljc +241 -0
- package/test/datahike/test/attribute_refs/temporal_search.cljc +22 -0
- package/test/datahike/test/attribute_refs/transact_test.cljc +220 -0
- package/test/datahike/test/attribute_refs/utils.cljc +128 -0
- package/test/datahike/test/cache_test.cljc +38 -0
- package/test/datahike/test/components_test.cljc +92 -0
- package/test/datahike/test/config_test.cljc +158 -0
- package/test/datahike/test/core_test.cljc +105 -0
- package/test/datahike/test/datom_test.cljc +44 -0
- package/test/datahike/test/db_test.cljc +54 -0
- package/test/datahike/test/entity_spec_test.cljc +159 -0
- package/test/datahike/test/entity_test.cljc +103 -0
- package/test/datahike/test/explode_test.cljc +143 -0
- package/test/datahike/test/filter_test.cljc +75 -0
- package/test/datahike/test/gc_test.cljc +159 -0
- package/test/datahike/test/http/server_test.clj +192 -0
- package/test/datahike/test/http/writer_test.clj +86 -0
- package/test/datahike/test/ident_test.cljc +32 -0
- package/test/datahike/test/index_test.cljc +345 -0
- package/test/datahike/test/insert.cljc +125 -0
- package/test/datahike/test/java_bindings_test.clj +6 -0
- package/test/datahike/test/listen_test.cljc +41 -0
- package/test/datahike/test/lookup_refs_test.cljc +266 -0
- package/test/datahike/test/lru_test.cljc +27 -0
- package/test/datahike/test/migrate_test.clj +297 -0
- package/test/datahike/test/model/core.cljc +376 -0
- package/test/datahike/test/model/invariant.cljc +142 -0
- package/test/datahike/test/model/rng.cljc +82 -0
- package/test/datahike/test/model_test.clj +217 -0
- package/test/datahike/test/nodejs_test.cljs +262 -0
- package/test/datahike/test/online_gc_test.cljc +475 -0
- package/test/datahike/test/pod_test.clj +369 -0
- package/test/datahike/test/pull_api_test.cljc +474 -0
- package/test/datahike/test/purge_test.cljc +144 -0
- package/test/datahike/test/query_aggregates_test.cljc +101 -0
- package/test/datahike/test/query_find_specs_test.cljc +52 -0
- package/test/datahike/test/query_fns_test.cljc +523 -0
- package/test/datahike/test/query_interop_test.cljc +47 -0
- package/test/datahike/test/query_not_test.cljc +189 -0
- package/test/datahike/test/query_or_test.cljc +158 -0
- package/test/datahike/test/query_pull_test.cljc +147 -0
- package/test/datahike/test/query_rules_test.cljc +248 -0
- package/test/datahike/test/query_stats_test.cljc +218 -0
- package/test/datahike/test/query_test.cljc +984 -0
- package/test/datahike/test/schema_test.cljc +424 -0
- package/test/datahike/test/specification_test.cljc +30 -0
- package/test/datahike/test/store_test.cljc +78 -0
- package/test/datahike/test/stress_test.cljc +57 -0
- package/test/datahike/test/time_variance_test.cljc +518 -0
- package/test/datahike/test/tools_test.clj +134 -0
- package/test/datahike/test/transact_test.cljc +518 -0
- package/test/datahike/test/tuples_test.cljc +564 -0
- package/test/datahike/test/unstructured_test.cljc +291 -0
- package/test/datahike/test/upsert_impl_test.cljc +205 -0
- package/test/datahike/test/upsert_test.cljc +363 -0
- package/test/datahike/test/utils.cljc +110 -0
- package/test/datahike/test/validation_test.cljc +48 -0
- package/test/datahike/test/versioning_test.cljc +56 -0
- package/test/datahike/test.cljc +66 -0
- package/tests.edn +24 -0
|
@@ -0,0 +1,569 @@
|
|
|
1
|
+
# Datahike Python Bindings
|
|
2
|
+
|
|
3
|
+
**Status: Beta** - API is functional and tested, but may receive breaking changes as we refine the bindings.
|
|
4
|
+
|
|
5
|
+
Python bindings for [Datahike](https://github.com/replikativ/datahike), a durable Datalog database powered by an efficient Datalog query engine.
|
|
6
|
+
|
|
7
|
+
## Features
|
|
8
|
+
|
|
9
|
+
- **Datalog queries** - Expressive declarative queries
|
|
10
|
+
- **Durable storage** - Persistent databases with ACID transactions
|
|
11
|
+
- **Time travel** - Query database history and point-in-time snapshots
|
|
12
|
+
- **Flexible schema** - Schema-on-write or schema-on-read
|
|
13
|
+
- **Pull API** - Recursive pattern-based entity retrieval
|
|
14
|
+
- **Multiple backends** - Memory, file system, and more
|
|
15
|
+
- **Pythonic API** - Work with Python dicts, not EDN strings
|
|
16
|
+
|
|
17
|
+
## Installation
|
|
18
|
+
|
|
19
|
+
### Prerequisites
|
|
20
|
+
|
|
21
|
+
- Python 3.8+
|
|
22
|
+
- GraalVM (for building native library)
|
|
23
|
+
- Babashka (for build tasks)
|
|
24
|
+
|
|
25
|
+
### Building from Source
|
|
26
|
+
|
|
27
|
+
```bash
|
|
28
|
+
# Clone the Datahike repository
|
|
29
|
+
git clone https://github.com/replikativ/datahike.git
|
|
30
|
+
cd datahike
|
|
31
|
+
|
|
32
|
+
# Build the native library
|
|
33
|
+
bb ni-compile
|
|
34
|
+
|
|
35
|
+
# Install Python package
|
|
36
|
+
pip install ./pydatahike
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
### Setting Library Path
|
|
40
|
+
|
|
41
|
+
If the library isn't found automatically, set the environment variable:
|
|
42
|
+
|
|
43
|
+
```bash
|
|
44
|
+
export LIBDATAHIKE_PATH=/path/to/datahike/libdatahike/target/libdatahike.so
|
|
45
|
+
```
|
|
46
|
+
|
|
47
|
+
## Quick Start
|
|
48
|
+
|
|
49
|
+
> **Note:** Memory backend requires UUID identifiers. Use `str(uuid.uuid4())` to generate unique IDs. This is required by the underlying konserve store and is essential for distributed database tracking.
|
|
50
|
+
|
|
51
|
+
```python
|
|
52
|
+
import uuid
|
|
53
|
+
from datahike import Database
|
|
54
|
+
|
|
55
|
+
# Create database
|
|
56
|
+
db = Database.memory(str(uuid.uuid4()))
|
|
57
|
+
db.create()
|
|
58
|
+
|
|
59
|
+
# Transact data
|
|
60
|
+
db.transact([
|
|
61
|
+
{"name": "Alice", "age": 30},
|
|
62
|
+
{"name": "Bob", "age": 25}
|
|
63
|
+
])
|
|
64
|
+
|
|
65
|
+
# Query with Datalog
|
|
66
|
+
result = db.q('[:find ?name ?age :where [?e :name ?name] [?e :age ?age]]')
|
|
67
|
+
print(result) # [['Alice', 30], ['Bob', 25]]
|
|
68
|
+
|
|
69
|
+
# Pull entity
|
|
70
|
+
entity = db.pull('[:name :age]', 1)
|
|
71
|
+
print(entity) # {':name': 'Alice', ':age': 30}
|
|
72
|
+
|
|
73
|
+
# Cleanup
|
|
74
|
+
db.delete()
|
|
75
|
+
```
|
|
76
|
+
|
|
77
|
+
## High-Level API (Recommended)
|
|
78
|
+
|
|
79
|
+
The high-level API provides a Pythonic interface using native Python data structures.
|
|
80
|
+
|
|
81
|
+
### Database Class
|
|
82
|
+
|
|
83
|
+
```python
|
|
84
|
+
import uuid
|
|
85
|
+
from datahike import Database
|
|
86
|
+
|
|
87
|
+
# Create in-memory database
|
|
88
|
+
db = Database.memory(str(uuid.uuid4()))
|
|
89
|
+
db.create()
|
|
90
|
+
|
|
91
|
+
# Create file-based database
|
|
92
|
+
db = Database.file("/tmp/mydb")
|
|
93
|
+
db.create()
|
|
94
|
+
|
|
95
|
+
# Create with full configuration (Python dict)
|
|
96
|
+
db = Database({
|
|
97
|
+
"store": {
|
|
98
|
+
"backend": ":memory",
|
|
99
|
+
"id": "mydb"
|
|
100
|
+
},
|
|
101
|
+
"schema-flexibility": ":read",
|
|
102
|
+
"keep-history?": True
|
|
103
|
+
})
|
|
104
|
+
db.create()
|
|
105
|
+
|
|
106
|
+
# Don't forget to delete when done
|
|
107
|
+
db.delete()
|
|
108
|
+
```
|
|
109
|
+
|
|
110
|
+
### Context Manager (Auto-Cleanup)
|
|
111
|
+
|
|
112
|
+
```python
|
|
113
|
+
import uuid
|
|
114
|
+
from datahike import database
|
|
115
|
+
|
|
116
|
+
# Database automatically created and deleted
|
|
117
|
+
with database(backend=':memory', id=str(uuid.uuid4())) as db:
|
|
118
|
+
db.transact([{"name": "Alice"}])
|
|
119
|
+
result = db.q('[:find ?name :where [?e :name ?name]]')
|
|
120
|
+
print(result) # [['Alice']]
|
|
121
|
+
# Database deleted when context exits
|
|
122
|
+
```
|
|
123
|
+
|
|
124
|
+
### Transactions with Python Dicts
|
|
125
|
+
|
|
126
|
+
```python
|
|
127
|
+
# Single entity
|
|
128
|
+
db.transact({"name": "Alice", "age": 30})
|
|
129
|
+
|
|
130
|
+
# Multiple entities
|
|
131
|
+
db.transact([
|
|
132
|
+
{"name": "Alice", "age": 30},
|
|
133
|
+
{"name": "Bob", "age": 25}
|
|
134
|
+
])
|
|
135
|
+
|
|
136
|
+
# Schema transaction with EDN helpers
|
|
137
|
+
from datahike import edn, kw
|
|
138
|
+
|
|
139
|
+
db.transact([{
|
|
140
|
+
kw.DB_IDENT: edn.keyword("person/name"),
|
|
141
|
+
kw.DB_VALUE_TYPE: kw.STRING,
|
|
142
|
+
kw.DB_CARDINALITY: kw.ONE,
|
|
143
|
+
kw.DB_DOC: "Person's full name"
|
|
144
|
+
}])
|
|
145
|
+
```
|
|
146
|
+
|
|
147
|
+
### Queries
|
|
148
|
+
|
|
149
|
+
```python
|
|
150
|
+
# Simple query
|
|
151
|
+
result = db.q('[:find ?name :where [?e :name ?name]]')
|
|
152
|
+
|
|
153
|
+
# Query with parameters
|
|
154
|
+
result = db.q(
|
|
155
|
+
'[:find ?e :in $ ?name :where [?e :name ?name]]',
|
|
156
|
+
('param', '"Alice"')
|
|
157
|
+
)
|
|
158
|
+
|
|
159
|
+
# Query multiple databases
|
|
160
|
+
other_db = Database.memory(str(uuid.uuid4()))
|
|
161
|
+
result = db.q(
|
|
162
|
+
'[:find ?name :in $ $2 :where [$ ?e :name ?name] [$2 ?e :active true]]',
|
|
163
|
+
other_db
|
|
164
|
+
)
|
|
165
|
+
```
|
|
166
|
+
|
|
167
|
+
### Time Travel
|
|
168
|
+
|
|
169
|
+
```python
|
|
170
|
+
import time
|
|
171
|
+
|
|
172
|
+
# Store current timestamp
|
|
173
|
+
t1 = int(time.time() * 1000)
|
|
174
|
+
db.transact({"name": "Alice", "status": ":active"})
|
|
175
|
+
|
|
176
|
+
time.sleep(0.1)
|
|
177
|
+
t2 = int(time.time() * 1000)
|
|
178
|
+
db.transact({"name": "Bob", "status": ":inactive"})
|
|
179
|
+
|
|
180
|
+
# Query current state
|
|
181
|
+
current = db.q('[:find ?name :where [?e :name ?name]]')
|
|
182
|
+
print(current) # [['Alice'], ['Bob']]
|
|
183
|
+
|
|
184
|
+
# Query as of t1 (before Bob was added)
|
|
185
|
+
past = db.as_of(t1)
|
|
186
|
+
result = past.q('[:find ?name :where [?e :name ?name]]')
|
|
187
|
+
print(result) # [['Alice']]
|
|
188
|
+
|
|
189
|
+
# Query changes since t1
|
|
190
|
+
changes = db.since(t1)
|
|
191
|
+
result = changes.q('[:find ?name :where [?e :name ?name]]')
|
|
192
|
+
print(result) # [['Bob']]
|
|
193
|
+
|
|
194
|
+
# Query full history
|
|
195
|
+
history = db.history
|
|
196
|
+
result = history.q('[:find ?name :where [?e :name ?name]]')
|
|
197
|
+
print(result) # All historical values
|
|
198
|
+
```
|
|
199
|
+
|
|
200
|
+
## EDN Conversion Rules
|
|
201
|
+
|
|
202
|
+
Datahike uses [EDN (Extensible Data Notation)](https://github.com/edn-format/edn), Clojure's data format. The Python bindings automatically convert between Python and EDN using simple, predictable rules:
|
|
203
|
+
|
|
204
|
+
### The Universal Rule
|
|
205
|
+
|
|
206
|
+
> **Keys are always keywordized. Values starting with `:` become keywords, everything else remains literal.**
|
|
207
|
+
|
|
208
|
+
### Examples
|
|
209
|
+
|
|
210
|
+
```python
|
|
211
|
+
# Python dict → EDN map
|
|
212
|
+
{
|
|
213
|
+
"store": {
|
|
214
|
+
"backend": ":memory", # ":memory" → :memory (keyword)
|
|
215
|
+
"id": "test" # "test" → "test" (string)
|
|
216
|
+
},
|
|
217
|
+
"schema-flexibility": ":read", # ":read" → :read (keyword)
|
|
218
|
+
"keep-history?": True # True → true (boolean)
|
|
219
|
+
}
|
|
220
|
+
# → {:store {:backend :memory :id "test"}
|
|
221
|
+
# :schema-flexibility :read
|
|
222
|
+
# :keep-history? true}
|
|
223
|
+
|
|
224
|
+
# Transaction data
|
|
225
|
+
[
|
|
226
|
+
{"name": "Alice", "status": ":active"}, # "Alice" → string, ":active" → keyword
|
|
227
|
+
{"name": "Bob", "age": 25} # 25 → number
|
|
228
|
+
]
|
|
229
|
+
# → [{:name "Alice" :status :active}
|
|
230
|
+
# {:name "Bob" :age 25}]
|
|
231
|
+
```
|
|
232
|
+
|
|
233
|
+
### Escape Hatches
|
|
234
|
+
|
|
235
|
+
For fine-grained control, use the `edn` helper module:
|
|
236
|
+
|
|
237
|
+
```python
|
|
238
|
+
from datahike import edn, kw
|
|
239
|
+
|
|
240
|
+
# Explicit keyword construction
|
|
241
|
+
edn.keyword("name") # → :name
|
|
242
|
+
edn.keyword("name", "person") # → :person/name
|
|
243
|
+
|
|
244
|
+
# Force string (even with : prefix)
|
|
245
|
+
edn.string(":literal-colon") # → ":literal-colon" (string, not keyword)
|
|
246
|
+
|
|
247
|
+
# UUID and timestamps
|
|
248
|
+
edn.uuid("550e8400-e29b-41d4-a716-446655440000") # → #uuid "..."
|
|
249
|
+
edn.inst("2024-01-01T00:00:00Z") # → #inst "..."
|
|
250
|
+
|
|
251
|
+
# Pre-defined constants (avoid typos)
|
|
252
|
+
kw.DB_ID # → ":db/id"
|
|
253
|
+
kw.DB_IDENT # → ":db/ident"
|
|
254
|
+
kw.DB_VALUE_TYPE # → ":db/valueType"
|
|
255
|
+
kw.STRING # → ":db.type/string"
|
|
256
|
+
kw.ONE # → ":db.cardinality/one"
|
|
257
|
+
```
|
|
258
|
+
|
|
259
|
+
For complete EDN conversion rules and edge cases, see [EDN Conversion Documentation](../doc/bindings/edn-conversion.md).
|
|
260
|
+
|
|
261
|
+
## Usage Examples
|
|
262
|
+
|
|
263
|
+
### Schema Definition
|
|
264
|
+
|
|
265
|
+
```python
|
|
266
|
+
import uuid
|
|
267
|
+
from datahike import Database, edn, kw
|
|
268
|
+
|
|
269
|
+
db = Database.memory(str(uuid.uuid4()))
|
|
270
|
+
db.create()
|
|
271
|
+
|
|
272
|
+
# Define schema using Python dicts and EDN helpers
|
|
273
|
+
schema = [{
|
|
274
|
+
kw.DB_IDENT: edn.keyword("person/name"),
|
|
275
|
+
kw.DB_VALUE_TYPE: kw.STRING,
|
|
276
|
+
kw.DB_CARDINALITY: kw.ONE,
|
|
277
|
+
kw.DB_DOC: "Person's full name"
|
|
278
|
+
}, {
|
|
279
|
+
kw.DB_IDENT: edn.keyword("person/age"),
|
|
280
|
+
kw.DB_VALUE_TYPE: kw.LONG,
|
|
281
|
+
kw.DB_CARDINALITY: kw.ONE
|
|
282
|
+
}, {
|
|
283
|
+
kw.DB_IDENT: edn.keyword("person/friends"),
|
|
284
|
+
kw.DB_VALUE_TYPE: kw.REF,
|
|
285
|
+
kw.DB_CARDINALITY: kw.MANY,
|
|
286
|
+
kw.DB_DOC: "Person's friends (refs)"
|
|
287
|
+
}]
|
|
288
|
+
|
|
289
|
+
db.transact(schema)
|
|
290
|
+
|
|
291
|
+
# Get schema
|
|
292
|
+
db_schema = db.schema()
|
|
293
|
+
print(db_schema)
|
|
294
|
+
```
|
|
295
|
+
|
|
296
|
+
### Pull API
|
|
297
|
+
|
|
298
|
+
```python
|
|
299
|
+
# Pull single entity
|
|
300
|
+
entity = db.pull('[:name :age]', 1)
|
|
301
|
+
|
|
302
|
+
# Pull with wildcard
|
|
303
|
+
entity = db.pull('[*]', 1)
|
|
304
|
+
|
|
305
|
+
# Pull with relationships
|
|
306
|
+
pattern = '[:name {:friends [:name]}]'
|
|
307
|
+
entity = db.pull(pattern, 1)
|
|
308
|
+
|
|
309
|
+
# Pull multiple entities
|
|
310
|
+
entities = db.pull_many('[:name]', [1, 2, 3])
|
|
311
|
+
```
|
|
312
|
+
|
|
313
|
+
### Custom Backends
|
|
314
|
+
|
|
315
|
+
The dict-based API naturally supports custom backends with arbitrary configuration:
|
|
316
|
+
|
|
317
|
+
```python
|
|
318
|
+
# Custom S3 backend (hypothetical)
|
|
319
|
+
db = Database({
|
|
320
|
+
"store": {
|
|
321
|
+
"backend": ":my-s3",
|
|
322
|
+
"bucket": "my-bucket",
|
|
323
|
+
"region": "us-west-2",
|
|
324
|
+
"encryption": {
|
|
325
|
+
"type": ":aes256",
|
|
326
|
+
"key-id": "secret-key"
|
|
327
|
+
}
|
|
328
|
+
}
|
|
329
|
+
})
|
|
330
|
+
db.create()
|
|
331
|
+
```
|
|
332
|
+
|
|
333
|
+
### Index Operations
|
|
334
|
+
|
|
335
|
+
```python
|
|
336
|
+
# Get datoms from index
|
|
337
|
+
datoms = db.datoms(':eavt')
|
|
338
|
+
|
|
339
|
+
# Seek to position in index
|
|
340
|
+
datoms = db.seek_datoms(':avet', [':name', '"Alice"'])
|
|
341
|
+
|
|
342
|
+
# Get index range
|
|
343
|
+
range_data = db.index_range(':name', '"A"', '"M"')
|
|
344
|
+
```
|
|
345
|
+
|
|
346
|
+
### Error Handling
|
|
347
|
+
|
|
348
|
+
```python
|
|
349
|
+
import uuid
|
|
350
|
+
from datahike import Database, DatahikeException
|
|
351
|
+
|
|
352
|
+
db = Database.memory(str(uuid.uuid4()))
|
|
353
|
+
db.create()
|
|
354
|
+
|
|
355
|
+
try:
|
|
356
|
+
result = db.q('[:find ?e :where [?e :nonexistent]]')
|
|
357
|
+
except DatahikeException as e:
|
|
358
|
+
print(f"Query failed: {e}")
|
|
359
|
+
```
|
|
360
|
+
|
|
361
|
+
## Advanced: Low-Level API
|
|
362
|
+
|
|
363
|
+
For advanced use cases, you can use the low-level API that works directly with EDN strings:
|
|
364
|
+
|
|
365
|
+
```python
|
|
366
|
+
from datahike import create_database, delete_database, transact, q
|
|
367
|
+
|
|
368
|
+
# Create database with EDN config
|
|
369
|
+
config = '{:store {:backend :memory :id "lowlevel"}}'
|
|
370
|
+
create_database(config)
|
|
371
|
+
|
|
372
|
+
# Transact EDN data
|
|
373
|
+
transact(config, '[{:name "Alice" :age 30}]')
|
|
374
|
+
|
|
375
|
+
# Query with explicit inputs
|
|
376
|
+
result = q(
|
|
377
|
+
'[:find ?name ?age :where [?e :name ?name] [?e :age ?age]]',
|
|
378
|
+
[('db', config)],
|
|
379
|
+
output_format='cbor'
|
|
380
|
+
)
|
|
381
|
+
|
|
382
|
+
# Cleanup
|
|
383
|
+
delete_database(config)
|
|
384
|
+
```
|
|
385
|
+
|
|
386
|
+
The low-level API gives you full control over EDN serialization and output formats, but requires manual string construction.
|
|
387
|
+
|
|
388
|
+
## Output Formats
|
|
389
|
+
|
|
390
|
+
All query and retrieval functions support multiple output formats:
|
|
391
|
+
|
|
392
|
+
- `cbor` (default) - Compact binary format, best for structured data
|
|
393
|
+
- `json` - Human-readable, good for debugging
|
|
394
|
+
- `edn` - Clojure data format (returned as string)
|
|
395
|
+
|
|
396
|
+
```python
|
|
397
|
+
# High-level API
|
|
398
|
+
result = db.q(query, output_format='json')
|
|
399
|
+
|
|
400
|
+
# Low-level API
|
|
401
|
+
result = q(query, inputs, output_format='edn')
|
|
402
|
+
```
|
|
403
|
+
|
|
404
|
+
## API Reference
|
|
405
|
+
|
|
406
|
+
### High-Level API
|
|
407
|
+
|
|
408
|
+
#### Database Class
|
|
409
|
+
|
|
410
|
+
**Factory Methods:**
|
|
411
|
+
- `Database.memory(id)` - Create in-memory database config. **Important:** `id` must be a UUID string (use `str(uuid.uuid4())`)
|
|
412
|
+
- `Database.file(path)` - Create file-based database config
|
|
413
|
+
- `Database(config_dict)` - Create from Python dict
|
|
414
|
+
- `Database(edn_string)` - Create from EDN string
|
|
415
|
+
|
|
416
|
+
**Lifecycle:**
|
|
417
|
+
- `db.create()` - Create the database
|
|
418
|
+
- `db.delete()` - Delete the database
|
|
419
|
+
- `db.exists()` - Check if database exists
|
|
420
|
+
|
|
421
|
+
**Transactions:**
|
|
422
|
+
- `db.transact(data, input_format='json')` - Execute transaction with Python dict/list
|
|
423
|
+
|
|
424
|
+
**Queries:**
|
|
425
|
+
- `db.q(query, *args, **kwargs)` - Execute Datalog query
|
|
426
|
+
- `db.pull(selector, eid)` - Pull entity by pattern
|
|
427
|
+
- `db.pull_many(selector, eids)` - Pull multiple entities
|
|
428
|
+
- `db.entity(eid)` - Get entity by ID
|
|
429
|
+
|
|
430
|
+
**Time Travel:**
|
|
431
|
+
- `db.as_of(timestamp_ms)` - Return DatabaseSnapshot at point in time
|
|
432
|
+
- `db.since(timestamp_ms)` - Return DatabaseSnapshot with changes since time
|
|
433
|
+
- `db.history` - Return DatabaseSnapshot with full history
|
|
434
|
+
|
|
435
|
+
**Schema & Metadata:**
|
|
436
|
+
- `db.schema()` - Get database schema
|
|
437
|
+
- `db.reverse_schema()` - Get reverse schema mapping
|
|
438
|
+
- `db.metrics()` - Get database metrics
|
|
439
|
+
|
|
440
|
+
**Index Operations:**
|
|
441
|
+
- `db.datoms(index)` - Get datoms from index
|
|
442
|
+
- `db.seek_datoms(index, components)` - Seek to position in index
|
|
443
|
+
- `db.index_range(attr, start, end)` - Get index range
|
|
444
|
+
|
|
445
|
+
**Maintenance:**
|
|
446
|
+
- `db.gc_storage()` - Garbage collect storage
|
|
447
|
+
|
|
448
|
+
#### Context Manager
|
|
449
|
+
|
|
450
|
+
- `database(**kwargs)` - Context manager for automatic database lifecycle
|
|
451
|
+
- `database(config_dict)` - Context manager with dict config
|
|
452
|
+
|
|
453
|
+
#### EDN Helpers
|
|
454
|
+
|
|
455
|
+
**Types:**
|
|
456
|
+
- `edn.keyword(name, namespace=None)` - Create EDN keyword
|
|
457
|
+
- `edn.symbol(name, namespace=None)` - Create EDN symbol
|
|
458
|
+
- `edn.uuid(value)` - Create EDN UUID
|
|
459
|
+
- `edn.inst(value)` - Create EDN instant (timestamp)
|
|
460
|
+
- `edn.string(value)` - Force string (escape : prefix)
|
|
461
|
+
|
|
462
|
+
**Constants (`kw` object):**
|
|
463
|
+
- `kw.DB_ID`, `kw.DB_IDENT`
|
|
464
|
+
- `kw.DB_VALUE_TYPE`, `kw.DB_CARDINALITY`, `kw.DB_DOC`
|
|
465
|
+
- `kw.DB_UNIQUE`, `kw.DB_IS_COMPONENT`, `kw.DB_NO_HISTORY`
|
|
466
|
+
- `kw.STRING`, `kw.BOOLEAN`, `kw.LONG`, `kw.BIGINT`, `kw.FLOAT`, `kw.DOUBLE`
|
|
467
|
+
- `kw.INSTANT`, `kw.UUID_TYPE`, `kw.KEYWORD_TYPE`, `kw.SYMBOL_TYPE`
|
|
468
|
+
- `kw.REF`, `kw.BYTES`
|
|
469
|
+
- `kw.ONE`, `kw.MANY`
|
|
470
|
+
- `kw.UNIQUE_VALUE`, `kw.UNIQUE_IDENTITY`
|
|
471
|
+
- `kw.SCHEMA_READ`, `kw.SCHEMA_WRITE`
|
|
472
|
+
|
|
473
|
+
### Low-Level API
|
|
474
|
+
|
|
475
|
+
**Database Operations:**
|
|
476
|
+
- `create_database(config)` - Create a new database
|
|
477
|
+
- `delete_database(config)` - Delete a database
|
|
478
|
+
- `database_exists(config)` - Check if database exists
|
|
479
|
+
|
|
480
|
+
**Data Operations:**
|
|
481
|
+
- `transact(config, tx_data, input_format='edn')` - Execute transaction
|
|
482
|
+
- `q(query, inputs, output_format='cbor')` - Execute Datalog query
|
|
483
|
+
- `pull(config, selector, eid, output_format='cbor')` - Pull entity
|
|
484
|
+
- `pull_many(config, selector, eids, output_format='cbor')` - Pull multiple
|
|
485
|
+
- `entity(config, eid, output_format='cbor')` - Get entity by ID
|
|
486
|
+
|
|
487
|
+
**Index Operations:**
|
|
488
|
+
- `datoms(config, index, output_format='cbor')` - Get datoms
|
|
489
|
+
- `seek_datoms(config, index, components, output_format='cbor')` - Seek datoms
|
|
490
|
+
- `index_range(config, attr, start, end, output_format='cbor')` - Get range
|
|
491
|
+
|
|
492
|
+
**Schema & Metadata:**
|
|
493
|
+
- `schema(config, output_format='cbor')` - Get schema
|
|
494
|
+
- `reverse_schema(config, output_format='cbor')` - Get reverse schema
|
|
495
|
+
- `metrics(config, output_format='cbor')` - Get metrics
|
|
496
|
+
|
|
497
|
+
**Maintenance:**
|
|
498
|
+
- `gc_storage(config)` - Garbage collect storage
|
|
499
|
+
|
|
500
|
+
## Development
|
|
501
|
+
|
|
502
|
+
### Running Tests
|
|
503
|
+
|
|
504
|
+
```bash
|
|
505
|
+
# Build native library first
|
|
506
|
+
cd datahike && bb ni-compile
|
|
507
|
+
|
|
508
|
+
# Run all tests
|
|
509
|
+
cd pydatahike
|
|
510
|
+
python -m pytest tests/ -v
|
|
511
|
+
|
|
512
|
+
# Run specific test file
|
|
513
|
+
python -m pytest tests/test_edn_conversion.py -v
|
|
514
|
+
```
|
|
515
|
+
|
|
516
|
+
### Type Checking
|
|
517
|
+
|
|
518
|
+
```bash
|
|
519
|
+
pip install mypy
|
|
520
|
+
mypy src/datahike
|
|
521
|
+
```
|
|
522
|
+
|
|
523
|
+
## Migration from Low-Level API
|
|
524
|
+
|
|
525
|
+
If you're using the low-level API with EDN strings, migrating to the high-level API is straightforward:
|
|
526
|
+
|
|
527
|
+
**Before:**
|
|
528
|
+
```python
|
|
529
|
+
from datahike import create_database, transact, q, delete_database
|
|
530
|
+
|
|
531
|
+
config = '{:store {:backend :memory :id "mydb"}}'
|
|
532
|
+
create_database(config)
|
|
533
|
+
transact(config, '[{:name "Alice"}]')
|
|
534
|
+
result = q('[:find ?name :where [?e :name ?name]]', [('db', config)])
|
|
535
|
+
delete_database(config)
|
|
536
|
+
```
|
|
537
|
+
|
|
538
|
+
**After:**
|
|
539
|
+
```python
|
|
540
|
+
import uuid
|
|
541
|
+
from datahike import Database
|
|
542
|
+
|
|
543
|
+
db = Database.memory(str(uuid.uuid4()))
|
|
544
|
+
db.create()
|
|
545
|
+
db.transact({"name": "Alice"})
|
|
546
|
+
result = db.q('[:find ?name :where [?e :name ?name]]')
|
|
547
|
+
db.delete()
|
|
548
|
+
```
|
|
549
|
+
|
|
550
|
+
**Or with context manager:**
|
|
551
|
+
```python
|
|
552
|
+
import uuid
|
|
553
|
+
from datahike import database
|
|
554
|
+
|
|
555
|
+
with database(backend=':memory', id=str(uuid.uuid4())) as db:
|
|
556
|
+
db.transact({"name": "Alice"})
|
|
557
|
+
result = db.q('[:find ?name :where [?e :name ?name]]')
|
|
558
|
+
```
|
|
559
|
+
|
|
560
|
+
## License
|
|
561
|
+
|
|
562
|
+
Eclipse Public License 1.0 (EPL-1.0)
|
|
563
|
+
|
|
564
|
+
## Links
|
|
565
|
+
|
|
566
|
+
- [Datahike GitHub](https://github.com/replikativ/datahike)
|
|
567
|
+
- [Datahike Documentation](https://github.com/replikativ/datahike/blob/main/doc/index.md)
|
|
568
|
+
- [EDN Conversion Rules](../doc/bindings/edn-conversion.md)
|
|
569
|
+
- [Datalog Tutorial](https://docs.datomic.com/on-prem/query.html)
|
|
@@ -0,0 +1,91 @@
|
|
|
1
|
+
[build-system]
|
|
2
|
+
requires = ["setuptools>=61.0", "wheel"]
|
|
3
|
+
build-backend = "setuptools.build_meta"
|
|
4
|
+
|
|
5
|
+
[project]
|
|
6
|
+
name = "datahike"
|
|
7
|
+
dynamic = ["version"]
|
|
8
|
+
description = "Python bindings for Datahike - a durable Datalog database"
|
|
9
|
+
readme = "README.md"
|
|
10
|
+
requires-python = ">=3.8"
|
|
11
|
+
license = {text = "EPL-1.0"}
|
|
12
|
+
authors = [
|
|
13
|
+
{name = "Datahike Team", email = "info@replikativ.io"}
|
|
14
|
+
]
|
|
15
|
+
keywords = ["datalog", "database", "datomic", "datascript", "query"]
|
|
16
|
+
classifiers = [
|
|
17
|
+
"Development Status :: 4 - Beta",
|
|
18
|
+
"Intended Audience :: Developers",
|
|
19
|
+
"License :: OSI Approved :: Eclipse Public License 1.0 (EPL-1.0)",
|
|
20
|
+
"Programming Language :: Python :: 3",
|
|
21
|
+
"Programming Language :: Python :: 3.8",
|
|
22
|
+
"Programming Language :: Python :: 3.9",
|
|
23
|
+
"Programming Language :: Python :: 3.10",
|
|
24
|
+
"Programming Language :: Python :: 3.11",
|
|
25
|
+
"Programming Language :: Python :: 3.12",
|
|
26
|
+
"Programming Language :: Python :: 3.13",
|
|
27
|
+
"Topic :: Database",
|
|
28
|
+
"Topic :: Database :: Database Engines/Servers",
|
|
29
|
+
"Typing :: Typed",
|
|
30
|
+
]
|
|
31
|
+
|
|
32
|
+
dependencies = [
|
|
33
|
+
"cbor2>=5.4.0",
|
|
34
|
+
]
|
|
35
|
+
|
|
36
|
+
[project.optional-dependencies]
|
|
37
|
+
dev = [
|
|
38
|
+
"pytest>=7.0",
|
|
39
|
+
"pytest-cov>=4.0",
|
|
40
|
+
"mypy>=1.0",
|
|
41
|
+
]
|
|
42
|
+
|
|
43
|
+
[project.urls]
|
|
44
|
+
Homepage = "https://github.com/replikativ/datahike"
|
|
45
|
+
Documentation = "https://github.com/replikativ/datahike/blob/main/doc/index.md"
|
|
46
|
+
Repository = "https://github.com/replikativ/datahike"
|
|
47
|
+
Issues = "https://github.com/replikativ/datahike/issues"
|
|
48
|
+
|
|
49
|
+
[tool.setuptools]
|
|
50
|
+
package-dir = {"" = "src"}
|
|
51
|
+
|
|
52
|
+
[tool.setuptools.packages.find]
|
|
53
|
+
where = ["src"]
|
|
54
|
+
|
|
55
|
+
[tool.setuptools.package-data]
|
|
56
|
+
datahike = ["py.typed"]
|
|
57
|
+
|
|
58
|
+
[tool.setuptools.dynamic]
|
|
59
|
+
version = {attr = "datahike._version.__version__"}
|
|
60
|
+
|
|
61
|
+
[tool.pytest.ini_options]
|
|
62
|
+
testpaths = ["tests"]
|
|
63
|
+
python_files = ["test_*.py"]
|
|
64
|
+
python_classes = ["Test*"]
|
|
65
|
+
python_functions = ["test_*"]
|
|
66
|
+
|
|
67
|
+
[tool.mypy]
|
|
68
|
+
python_version = "3.8"
|
|
69
|
+
warn_return_any = true
|
|
70
|
+
warn_unused_configs = true
|
|
71
|
+
disallow_untyped_defs = false
|
|
72
|
+
disallow_incomplete_defs = false
|
|
73
|
+
check_untyped_defs = true
|
|
74
|
+
no_implicit_optional = true
|
|
75
|
+
warn_redundant_casts = true
|
|
76
|
+
warn_unused_ignores = true
|
|
77
|
+
warn_no_return = true
|
|
78
|
+
|
|
79
|
+
[tool.coverage.run]
|
|
80
|
+
source = ["src/datahike"]
|
|
81
|
+
omit = ["*/tests/*"]
|
|
82
|
+
|
|
83
|
+
[tool.coverage.report]
|
|
84
|
+
exclude_lines = [
|
|
85
|
+
"pragma: no cover",
|
|
86
|
+
"def __repr__",
|
|
87
|
+
"raise AssertionError",
|
|
88
|
+
"raise NotImplementedError",
|
|
89
|
+
"if __name__ == .__main__.:",
|
|
90
|
+
"if TYPE_CHECKING:",
|
|
91
|
+
]
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
"""Datahike Python bindings setup."""
|
|
2
|
+
from setuptools import setup, find_packages
|
|
3
|
+
|
|
4
|
+
# Read version from _version.py
|
|
5
|
+
version = {}
|
|
6
|
+
with open("src/datahike/_version.py") as f:
|
|
7
|
+
exec(f.read(), version)
|
|
8
|
+
|
|
9
|
+
setup(
|
|
10
|
+
name='datahike',
|
|
11
|
+
version=version['__version__'],
|
|
12
|
+
description="Python bindings for Datahike - a durable Datalog database.",
|
|
13
|
+
long_description=open('README.md').read() if __import__('os').path.exists('README.md') else '',
|
|
14
|
+
long_description_content_type='text/markdown',
|
|
15
|
+
author='Datahike Team',
|
|
16
|
+
author_email='info@replikativ.io',
|
|
17
|
+
url='https://github.com/replikativ/datahike',
|
|
18
|
+
packages=find_packages("src"),
|
|
19
|
+
package_dir={"": "src"},
|
|
20
|
+
python_requires=">=3.8",
|
|
21
|
+
install_requires=[
|
|
22
|
+
'cbor2>=5.4.0',
|
|
23
|
+
],
|
|
24
|
+
extras_require={
|
|
25
|
+
'dev': [
|
|
26
|
+
'pytest>=7.0',
|
|
27
|
+
'pytest-cov>=4.0',
|
|
28
|
+
],
|
|
29
|
+
},
|
|
30
|
+
classifiers=[
|
|
31
|
+
'Development Status :: 4 - Beta',
|
|
32
|
+
'Intended Audience :: Developers',
|
|
33
|
+
'License :: OSI Approved :: Eclipse Public License 1.0 (EPL-1.0)',
|
|
34
|
+
'Programming Language :: Python :: 3',
|
|
35
|
+
'Programming Language :: Python :: 3.8',
|
|
36
|
+
'Programming Language :: Python :: 3.9',
|
|
37
|
+
'Programming Language :: Python :: 3.10',
|
|
38
|
+
'Programming Language :: Python :: 3.11',
|
|
39
|
+
'Programming Language :: Python :: 3.12',
|
|
40
|
+
'Topic :: Database',
|
|
41
|
+
],
|
|
42
|
+
)
|