linkml-store 0.0.0__tar.gz → 0.1.6__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.
Potentially problematic release.
This version of linkml-store might be problematic. Click here for more details.
- {linkml_store-0.0.0 → linkml_store-0.1.6}/PKG-INFO +17 -6
- linkml_store-0.1.6/README.md +10 -0
- {linkml_store-0.0.0 → linkml_store-0.1.6}/pyproject.toml +13 -4
- {linkml_store-0.0.0 → linkml_store-0.1.6}/src/linkml_store/api/__init__.py +2 -2
- {linkml_store-0.0.0 → linkml_store-0.1.6}/src/linkml_store/api/client.py +108 -7
- {linkml_store-0.0.0 → linkml_store-0.1.6}/src/linkml_store/api/collection.py +221 -30
- linkml_store-0.1.6/src/linkml_store/api/config.py +97 -0
- linkml_store-0.1.6/src/linkml_store/api/database.py +405 -0
- {linkml_store-0.0.0 → linkml_store-0.1.6}/src/linkml_store/api/queries.py +12 -1
- linkml_store-0.1.6/src/linkml_store/api/stores/chromadb/chromadb_collection.py +114 -0
- linkml_store-0.1.6/src/linkml_store/api/stores/chromadb/chromadb_database.py +89 -0
- {linkml_store-0.0.0 → linkml_store-0.1.6}/src/linkml_store/api/stores/duckdb/duckdb_collection.py +47 -14
- {linkml_store-0.0.0 → linkml_store-0.1.6}/src/linkml_store/api/stores/duckdb/duckdb_database.py +35 -44
- linkml_store-0.1.6/src/linkml_store/api/stores/hdf5/hdf5_collection.py +104 -0
- linkml_store-0.1.6/src/linkml_store/api/stores/hdf5/hdf5_database.py +79 -0
- linkml_store-0.1.6/src/linkml_store/api/stores/mongodb/mongodb_collection.py +102 -0
- linkml_store-0.1.6/src/linkml_store/api/stores/mongodb/mongodb_database.py +103 -0
- linkml_store-0.1.6/src/linkml_store/api/stores/solr/solr_collection.py +132 -0
- linkml_store-0.1.6/src/linkml_store/api/stores/solr/solr_database.py +82 -0
- linkml_store-0.1.6/src/linkml_store/cli.py +369 -0
- linkml_store-0.1.6/src/linkml_store/index/__init__.py +33 -0
- linkml_store-0.1.6/src/linkml_store/index/implementations/__init__.py +0 -0
- linkml_store-0.0.0/src/linkml_store/index/implementations/llm_index.py → linkml_store-0.1.6/src/linkml_store/index/implementations/llm_indexer.py +2 -2
- linkml_store-0.0.0/src/linkml_store/index/implementations/simple_index.py → linkml_store-0.1.6/src/linkml_store/index/implementations/simple_indexer.py +6 -3
- linkml_store-0.0.0/src/linkml_store/index/index.py → linkml_store-0.1.6/src/linkml_store/index/indexer.py +7 -4
- linkml_store-0.1.6/src/linkml_store/utils/__init__.py +0 -0
- linkml_store-0.1.6/src/linkml_store/utils/format_utils.py +93 -0
- linkml_store-0.1.6/src/linkml_store/utils/object_utils.py +73 -0
- {linkml_store-0.0.0 → linkml_store-0.1.6}/src/linkml_store/utils/sql_utils.py +46 -7
- linkml_store-0.0.0/README.md +0 -7
- linkml_store-0.0.0/src/linkml_store/api/database.py +0 -215
- linkml_store-0.0.0/src/linkml_store/api/metadata.py +0 -5
- linkml_store-0.0.0/src/linkml_store/api/stores/mongodb/mongodb_collection.py +0 -56
- linkml_store-0.0.0/src/linkml_store/api/stores/mongodb/mongodb_database.py +0 -112
- {linkml_store-0.0.0 → linkml_store-0.1.6}/LICENSE +0 -0
- {linkml_store-0.0.0 → linkml_store-0.1.6}/src/linkml_store/__init__.py +0 -0
- {linkml_store-0.0.0 → linkml_store-0.1.6}/src/linkml_store/api/stores/__init__.py +0 -0
- {linkml_store-0.0.0/src/linkml_store/api/stores/duckdb → linkml_store-0.1.6/src/linkml_store/api/stores/chromadb}/__init__.py +0 -0
- {linkml_store-0.0.0/src/linkml_store/api/stores/mongodb → linkml_store-0.1.6/src/linkml_store/api/stores/duckdb}/__init__.py +0 -0
- {linkml_store-0.0.0 → linkml_store-0.1.6}/src/linkml_store/api/stores/duckdb/mappings.py +0 -0
- {linkml_store-0.0.0/src/linkml_store/index → linkml_store-0.1.6/src/linkml_store/api/stores/hdf5}/__init__.py +0 -0
- {linkml_store-0.0.0/src/linkml_store/index/implementations → linkml_store-0.1.6/src/linkml_store/api/stores/mongodb}/__init__.py +0 -0
- /linkml_store-0.0.0/src/linkml_store/utils/__init__.py → /linkml_store-0.1.6/src/linkml_store/api/stores/solr/solr_utils.py +0 -0
- {linkml_store-0.0.0 → linkml_store-0.1.6}/src/linkml_store/constants.py +0 -0
- {linkml_store-0.0.0 → linkml_store-0.1.6}/src/linkml_store/utils/io.py +0 -0
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
Metadata-Version: 2.1
|
|
2
2
|
Name: linkml-store
|
|
3
|
-
Version: 0.
|
|
3
|
+
Version: 0.1.6
|
|
4
4
|
Summary: linkml-store
|
|
5
5
|
License: MIT
|
|
6
6
|
Author: Author 1
|
|
@@ -14,17 +14,25 @@ Classifier: Programming Language :: Python :: 3.11
|
|
|
14
14
|
Classifier: Programming Language :: Python :: 3.12
|
|
15
15
|
Provides-Extra: analytics
|
|
16
16
|
Provides-Extra: app
|
|
17
|
+
Provides-Extra: chromadb
|
|
18
|
+
Provides-Extra: h5py
|
|
17
19
|
Provides-Extra: llm
|
|
20
|
+
Provides-Extra: map
|
|
18
21
|
Provides-Extra: mongodb
|
|
19
22
|
Provides-Extra: tests
|
|
23
|
+
Provides-Extra: validation
|
|
20
24
|
Requires-Dist: black (>=24.0.0) ; extra == "tests"
|
|
25
|
+
Requires-Dist: chromadb ; extra == "chromadb"
|
|
21
26
|
Requires-Dist: click
|
|
22
27
|
Requires-Dist: duckdb (>=0.10.1,<0.11.0)
|
|
23
|
-
Requires-Dist: duckdb-engine (>=0.11.2
|
|
28
|
+
Requires-Dist: duckdb-engine (>=0.11.2)
|
|
29
|
+
Requires-Dist: h5py ; extra == "h5py"
|
|
30
|
+
Requires-Dist: linkml ; extra == "validation"
|
|
24
31
|
Requires-Dist: linkml-runtime (>=1.7.5,<2.0.0)
|
|
32
|
+
Requires-Dist: linkml_map ; extra == "map"
|
|
25
33
|
Requires-Dist: llm ; extra == "llm"
|
|
26
34
|
Requires-Dist: matplotlib ; extra == "analytics"
|
|
27
|
-
Requires-Dist: pandas (>=2.2.1
|
|
35
|
+
Requires-Dist: pandas (>=2.2.1) ; extra == "analytics"
|
|
28
36
|
Requires-Dist: plotly ; extra == "analytics"
|
|
29
37
|
Requires-Dist: pydantic (>=2.0.0,<3.0.0)
|
|
30
38
|
Requires-Dist: pymongo ; extra == "mongodb"
|
|
@@ -36,9 +44,12 @@ Description-Content-Type: text/markdown
|
|
|
36
44
|
|
|
37
45
|
# linkml-store
|
|
38
46
|
|
|
39
|
-
|
|
47
|
+
An integration layer for multiple database backends
|
|
40
48
|
|
|
41
|
-
|
|
49
|
+
Currently this software is alpha, and has only been tested with DuckDB backends. See the Tutorial for more information.
|
|
42
50
|
|
|
43
|
-
|
|
51
|
+
There is also experimental support for vector-based indexing using OpenAI test embedding via the `llm` library.
|
|
52
|
+
|
|
53
|
+
The goals of this project are to provide high level access to data stored in heterogeneous databases,
|
|
54
|
+
with optional schema management using LinkML.
|
|
44
55
|
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
# linkml-store
|
|
2
|
+
|
|
3
|
+
An integration layer for multiple database backends
|
|
4
|
+
|
|
5
|
+
Currently this software is alpha, and has only been tested with DuckDB backends. See the Tutorial for more information.
|
|
6
|
+
|
|
7
|
+
There is also experimental support for vector-based indexing using OpenAI test embedding via the `llm` library.
|
|
8
|
+
|
|
9
|
+
The goals of this project are to provide high level access to data stored in heterogeneous databases,
|
|
10
|
+
with optional schema management using LinkML.
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "linkml-store"
|
|
3
|
-
version = "0.
|
|
3
|
+
version = "0.1.6"
|
|
4
4
|
description = "linkml-store"
|
|
5
5
|
authors = ["Author 1 <author@org.org>"]
|
|
6
6
|
license = "MIT"
|
|
@@ -14,7 +14,7 @@ linkml-runtime = "^1.7.5"
|
|
|
14
14
|
streamlit = { version = "^1.32.2", optional = true }
|
|
15
15
|
sqlalchemy = "*"
|
|
16
16
|
duckdb = "^0.10.1"
|
|
17
|
-
duckdb-engine = "
|
|
17
|
+
duckdb-engine = ">=0.11.2"
|
|
18
18
|
matplotlib = { version = "*", optional = true }
|
|
19
19
|
seaborn = { version = "*", optional = true }
|
|
20
20
|
plotly = { version = "*", optional = true }
|
|
@@ -22,7 +22,11 @@ pystow = "^0.5.4"
|
|
|
22
22
|
black = { version=">=24.0.0", optional = true }
|
|
23
23
|
llm = { version="*", optional = true }
|
|
24
24
|
pymongo = { version="*", optional = true }
|
|
25
|
-
|
|
25
|
+
chromadb = { version="*", optional = true }
|
|
26
|
+
h5py = { version="*", optional = true }
|
|
27
|
+
linkml = { version="*", optional = true }
|
|
28
|
+
linkml_map = { version="*", optional = true }
|
|
29
|
+
pandas = ">=2.2.1"
|
|
26
30
|
|
|
27
31
|
[tool.poetry.group.dev.dependencies]
|
|
28
32
|
pytest = {version = ">=7.1.2"}
|
|
@@ -33,6 +37,7 @@ sphinx-rtd-theme = {version = ">=1.0.0"}
|
|
|
33
37
|
sphinx-autodoc-typehints = {version = "<2.0.0"}
|
|
34
38
|
sphinx-click = {version = ">=4.3.0"}
|
|
35
39
|
myst-parser = {version = ">=0.18.1"}
|
|
40
|
+
furo = {version = "*"}
|
|
36
41
|
nbsphinx = "*"
|
|
37
42
|
jupyter = "*"
|
|
38
43
|
|
|
@@ -50,9 +55,13 @@ app = ["streamlit"]
|
|
|
50
55
|
tests = ["black"]
|
|
51
56
|
llm = ["llm"]
|
|
52
57
|
mongodb = ["pymongo"]
|
|
58
|
+
chromadb = ["chromadb"]
|
|
59
|
+
h5py = ["h5py"]
|
|
60
|
+
validation = ["linkml"]
|
|
61
|
+
map = ["linkml_map"]
|
|
53
62
|
|
|
54
63
|
[tool.poetry.scripts]
|
|
55
|
-
linkml-store = "linkml_store.cli:
|
|
64
|
+
linkml-store = "linkml_store.cli:cli"
|
|
56
65
|
|
|
57
66
|
[tool.poetry-dynamic-versioning]
|
|
58
67
|
enable = false
|
|
@@ -1,8 +1,8 @@
|
|
|
1
1
|
# flake8: noqa: E402
|
|
2
2
|
from linkml_store.api.collection import Collection
|
|
3
3
|
from linkml_store.api.database import Database
|
|
4
|
-
from linkml_store.api.metadata import MetaData
|
|
5
4
|
from linkml_store.api.client import Client
|
|
5
|
+
|
|
6
6
|
# flake8: noqa
|
|
7
7
|
|
|
8
|
-
__all__ = ["Client", "Database", "
|
|
8
|
+
__all__ = ["Client", "Database", "Collection"]
|
|
@@ -1,17 +1,24 @@
|
|
|
1
|
-
from
|
|
2
|
-
from typing import Dict, Optional
|
|
1
|
+
from pathlib import Path
|
|
2
|
+
from typing import Dict, Optional, Union
|
|
3
3
|
|
|
4
|
+
import yaml
|
|
4
5
|
from linkml_runtime import SchemaView
|
|
5
6
|
|
|
6
7
|
from linkml_store.api import Database
|
|
8
|
+
from linkml_store.api.config import ClientConfig
|
|
9
|
+
from linkml_store.api.stores.chromadb.chromadb_database import ChromaDBDatabase
|
|
7
10
|
from linkml_store.api.stores.duckdb.duckdb_database import DuckDBDatabase
|
|
11
|
+
from linkml_store.api.stores.mongodb.mongodb_database import MongoDBDatabase
|
|
12
|
+
from linkml_store.api.stores.solr.solr_database import SolrDatabase
|
|
8
13
|
|
|
9
14
|
HANDLE_MAP = {
|
|
10
15
|
"duckdb": DuckDBDatabase,
|
|
16
|
+
"solr": SolrDatabase,
|
|
17
|
+
"mongodb": MongoDBDatabase,
|
|
18
|
+
"chromadb": ChromaDBDatabase,
|
|
11
19
|
}
|
|
12
20
|
|
|
13
21
|
|
|
14
|
-
@dataclass
|
|
15
22
|
class Client:
|
|
16
23
|
"""
|
|
17
24
|
A client provides access to named collections.
|
|
@@ -22,7 +29,7 @@ class Client:
|
|
|
22
29
|
>>> db = client.attach_database("duckdb", alias="test")
|
|
23
30
|
>>> collection = db.create_collection("Person")
|
|
24
31
|
>>> objs = [{"id": "P1", "name": "John", "age_in_years": 30}, {"id": "P2", "name": "Alice", "age_in_years": 25}]
|
|
25
|
-
>>> collection.
|
|
32
|
+
>>> collection.insert(objs)
|
|
26
33
|
>>> qr = collection.find()
|
|
27
34
|
>>> len(qr.rows)
|
|
28
35
|
2
|
|
@@ -38,9 +45,76 @@ class Client:
|
|
|
38
45
|
|
|
39
46
|
"""
|
|
40
47
|
|
|
41
|
-
|
|
48
|
+
metadata: Optional[ClientConfig] = None
|
|
42
49
|
_databases: Optional[Dict[str, Database]] = None
|
|
43
50
|
|
|
51
|
+
def __init__(self, handle: Optional[str] = None, metadata: Optional[ClientConfig] = None):
|
|
52
|
+
"""
|
|
53
|
+
Initialize a client.
|
|
54
|
+
|
|
55
|
+
:param handle:
|
|
56
|
+
:param metadata:
|
|
57
|
+
"""
|
|
58
|
+
self.metadata = metadata
|
|
59
|
+
if not self.metadata:
|
|
60
|
+
self.metadata = ClientConfig()
|
|
61
|
+
self.metadata.handle = handle
|
|
62
|
+
|
|
63
|
+
@property
|
|
64
|
+
def handle(self) -> Optional[str]:
|
|
65
|
+
return self.metadata.handle
|
|
66
|
+
|
|
67
|
+
@property
|
|
68
|
+
def base_dir(self) -> Optional[str]:
|
|
69
|
+
"""
|
|
70
|
+
Get the base directory for the client.
|
|
71
|
+
|
|
72
|
+
Wraps metadata.base_dir.
|
|
73
|
+
|
|
74
|
+
:return:
|
|
75
|
+
"""
|
|
76
|
+
return self.metadata.base_dir
|
|
77
|
+
|
|
78
|
+
def from_config(self, config: Union[ClientConfig, str, Path], base_dir=None, **kwargs):
|
|
79
|
+
"""
|
|
80
|
+
Create a client from a configuration.
|
|
81
|
+
|
|
82
|
+
Examples
|
|
83
|
+
--------
|
|
84
|
+
>>> from linkml_store.api.config import ClientConfig
|
|
85
|
+
>>> client = Client().from_config(ClientConfig(databases={"test": {"handle": "duckdb:///:memory:"}}))
|
|
86
|
+
>>> len(client.databases)
|
|
87
|
+
1
|
|
88
|
+
>>> "test" in client.databases
|
|
89
|
+
True
|
|
90
|
+
>>> client.databases["test"].handle
|
|
91
|
+
'duckdb:///:memory:'
|
|
92
|
+
|
|
93
|
+
:param config:
|
|
94
|
+
:param kwargs:
|
|
95
|
+
:return:
|
|
96
|
+
|
|
97
|
+
"""
|
|
98
|
+
if isinstance(config, Path):
|
|
99
|
+
config = str(config)
|
|
100
|
+
if isinstance(config, str):
|
|
101
|
+
if not base_dir:
|
|
102
|
+
base_dir = Path(config).parent
|
|
103
|
+
parsed_obj = yaml.safe_load(open(config))
|
|
104
|
+
config = ClientConfig(**parsed_obj)
|
|
105
|
+
self.metadata = config
|
|
106
|
+
if base_dir:
|
|
107
|
+
self.metadata.base_dir = base_dir
|
|
108
|
+
self._initialize_databases(**kwargs)
|
|
109
|
+
return self
|
|
110
|
+
|
|
111
|
+
def _initialize_databases(self, **kwargs):
|
|
112
|
+
for name, db_config in self.metadata.databases.items():
|
|
113
|
+
handle = db_config.handle.format(base_dir=self.base_dir)
|
|
114
|
+
db_config.handle = handle
|
|
115
|
+
db = self.attach_database(handle, alias=name, **kwargs)
|
|
116
|
+
db.from_config(db_config)
|
|
117
|
+
|
|
44
118
|
def attach_database(
|
|
45
119
|
self,
|
|
46
120
|
handle: str,
|
|
@@ -69,7 +143,6 @@ class Client:
|
|
|
69
143
|
:param schema_view: schema view to associate with the database
|
|
70
144
|
:param kwargs:
|
|
71
145
|
:return:
|
|
72
|
-
|
|
73
146
|
"""
|
|
74
147
|
if ":" not in handle:
|
|
75
148
|
scheme = handle
|
|
@@ -87,6 +160,7 @@ class Client:
|
|
|
87
160
|
if not self._databases:
|
|
88
161
|
self._databases = {}
|
|
89
162
|
self._databases[alias] = db
|
|
163
|
+
db.parent = self
|
|
90
164
|
return db
|
|
91
165
|
|
|
92
166
|
def get_database(self, name: Optional[str] = None, create_if_not_exists=True, **kwargs) -> Database:
|
|
@@ -101,7 +175,7 @@ class Client:
|
|
|
101
175
|
>>> db == retrieved_db
|
|
102
176
|
True
|
|
103
177
|
|
|
104
|
-
:param name:
|
|
178
|
+
:param name: if None, there must be a single database attached
|
|
105
179
|
:param create_if_not_exists:
|
|
106
180
|
:param kwargs:
|
|
107
181
|
:return:
|
|
@@ -149,3 +223,30 @@ class Client:
|
|
|
149
223
|
if not self._databases:
|
|
150
224
|
self._databases = {}
|
|
151
225
|
return self._databases
|
|
226
|
+
|
|
227
|
+
def drop_database(self, name: str, missing_ok=False, **kwargs):
|
|
228
|
+
"""
|
|
229
|
+
Drop a database.
|
|
230
|
+
|
|
231
|
+
:param name:
|
|
232
|
+
:param missing_ok:
|
|
233
|
+
:return:
|
|
234
|
+
"""
|
|
235
|
+
if name in self._databases:
|
|
236
|
+
db = self._databases[name]
|
|
237
|
+
db.drop(**kwargs)
|
|
238
|
+
del self._databases[name]
|
|
239
|
+
else:
|
|
240
|
+
if not missing_ok:
|
|
241
|
+
raise ValueError(f"Database {name} not found")
|
|
242
|
+
|
|
243
|
+
def drop_all_databases(self, **kwargs):
|
|
244
|
+
"""
|
|
245
|
+
Drop all databases.
|
|
246
|
+
|
|
247
|
+
:param missing_ok:
|
|
248
|
+
:return:
|
|
249
|
+
"""
|
|
250
|
+
for name in list(self._databases.keys()):
|
|
251
|
+
self.drop_database(name, missing_ok=False, **kwargs)
|
|
252
|
+
self._databases = {}
|