linkml-store 0.1.9__tar.gz → 0.1.11__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.1.11/PKG-INFO +171 -0
- linkml_store-0.1.11/README.md +115 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/pyproject.toml +12 -3
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/client.py +76 -11
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/collection.py +223 -40
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/config.py +59 -9
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/database.py +45 -27
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/duckdb/duckdb_collection.py +21 -3
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/duckdb/duckdb_database.py +36 -3
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/filesystem/filesystem_collection.py +13 -4
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/filesystem/filesystem_database.py +10 -1
- linkml_store-0.1.11/src/linkml_store/api/stores/mongodb/mongodb_collection.py +175 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/mongodb/mongodb_database.py +1 -36
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/solr/solr_collection.py +4 -4
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/cli.py +44 -18
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/index/__init__.py +21 -5
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/index/implementations/llm_indexer.py +2 -1
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/index/indexer.py +20 -4
- linkml_store-0.1.11/src/linkml_store/utils/file_utils.py +37 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/format_utils.py +69 -8
- linkml_store-0.1.11/src/linkml_store/utils/pandas_utils.py +40 -0
- linkml_store-0.1.11/src/linkml_store/utils/schema_utils.py +23 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/sql_utils.py +2 -1
- linkml_store-0.1.11/src/linkml_store/webapi/__init__.py +0 -0
- linkml_store-0.1.11/src/linkml_store/webapi/html/__init__.py +3 -0
- linkml_store-0.1.11/src/linkml_store/webapi/html/base.html.j2 +24 -0
- linkml_store-0.1.11/src/linkml_store/webapi/html/collection_details.html.j2 +15 -0
- linkml_store-0.1.11/src/linkml_store/webapi/html/database_details.html.j2 +16 -0
- linkml_store-0.1.11/src/linkml_store/webapi/html/databases.html.j2 +14 -0
- linkml_store-0.1.11/src/linkml_store/webapi/html/generic.html.j2 +46 -0
- linkml_store-0.1.11/src/linkml_store/webapi/main.py +572 -0
- linkml_store-0.1.9/PKG-INFO +0 -61
- linkml_store-0.1.9/README.md +0 -12
- linkml_store-0.1.9/src/linkml_store/api/stores/mongodb/mongodb_collection.py +0 -129
- {linkml_store-0.1.9 → linkml_store-0.1.11}/LICENSE +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/__init__.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/__init__.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/queries.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/__init__.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/chromadb/__init__.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/chromadb/chromadb_collection.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/chromadb/chromadb_database.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/duckdb/__init__.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/duckdb/mappings.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/filesystem/__init__.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/hdf5/__init__.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/hdf5/hdf5_collection.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/hdf5/hdf5_database.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/mongodb/__init__.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/solr/__init__.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/solr/solr_database.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/stores/solr/solr_utils.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/api/types.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/constants.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/index/implementations/__init__.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/index/implementations/simple_indexer.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/__init__.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/change_utils.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/io.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/object_utils.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/patch_utils.py +0 -0
- {linkml_store-0.1.9 → linkml_store-0.1.11}/src/linkml_store/utils/query_utils.py +0 -0
|
@@ -0,0 +1,171 @@
|
|
|
1
|
+
Metadata-Version: 2.1
|
|
2
|
+
Name: linkml-store
|
|
3
|
+
Version: 0.1.11
|
|
4
|
+
Summary: linkml-store
|
|
5
|
+
License: MIT
|
|
6
|
+
Author: Author 1
|
|
7
|
+
Author-email: author@org.org
|
|
8
|
+
Requires-Python: >=3.9, !=2.7.*, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*, !=3.4.*, !=3.5.*, !=3.6.*, !=3.7.*, !=3.8.*
|
|
9
|
+
Classifier: License :: OSI Approved :: MIT License
|
|
10
|
+
Classifier: Programming Language :: Python :: 3
|
|
11
|
+
Classifier: Programming Language :: Python :: 3.9
|
|
12
|
+
Classifier: Programming Language :: Python :: 3.10
|
|
13
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
14
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
15
|
+
Provides-Extra: analytics
|
|
16
|
+
Provides-Extra: app
|
|
17
|
+
Provides-Extra: chromadb
|
|
18
|
+
Provides-Extra: fastapi
|
|
19
|
+
Provides-Extra: frictionless
|
|
20
|
+
Provides-Extra: h5py
|
|
21
|
+
Provides-Extra: llm
|
|
22
|
+
Provides-Extra: map
|
|
23
|
+
Provides-Extra: mongodb
|
|
24
|
+
Provides-Extra: pyarrow
|
|
25
|
+
Provides-Extra: renderer
|
|
26
|
+
Provides-Extra: tests
|
|
27
|
+
Provides-Extra: validation
|
|
28
|
+
Requires-Dist: black (>=24.0.0) ; extra == "tests"
|
|
29
|
+
Requires-Dist: chromadb ; extra == "chromadb"
|
|
30
|
+
Requires-Dist: click
|
|
31
|
+
Requires-Dist: duckdb (>=0.10.1,<0.11.0)
|
|
32
|
+
Requires-Dist: duckdb-engine (>=0.11.2)
|
|
33
|
+
Requires-Dist: fastapi ; extra == "fastapi"
|
|
34
|
+
Requires-Dist: frictionless ; extra == "frictionless"
|
|
35
|
+
Requires-Dist: h5py ; extra == "h5py"
|
|
36
|
+
Requires-Dist: jinja2 (>=3.1.4,<4.0.0)
|
|
37
|
+
Requires-Dist: jsonlines (>=4.0.0,<5.0.0)
|
|
38
|
+
Requires-Dist: linkml (>=1.8.0) ; extra == "validation"
|
|
39
|
+
Requires-Dist: linkml-runtime (>=1.8.0)
|
|
40
|
+
Requires-Dist: linkml_map ; extra == "map"
|
|
41
|
+
Requires-Dist: linkml_renderer ; extra == "renderer"
|
|
42
|
+
Requires-Dist: llm ; extra == "llm"
|
|
43
|
+
Requires-Dist: matplotlib ; extra == "analytics"
|
|
44
|
+
Requires-Dist: pandas (>=2.2.1) ; extra == "analytics"
|
|
45
|
+
Requires-Dist: plotly ; extra == "analytics"
|
|
46
|
+
Requires-Dist: pyarrow ; extra == "pyarrow"
|
|
47
|
+
Requires-Dist: pydantic (>=2.0.0,<3.0.0)
|
|
48
|
+
Requires-Dist: pymongo ; extra == "mongodb"
|
|
49
|
+
Requires-Dist: pystow (>=0.5.4,<0.6.0)
|
|
50
|
+
Requires-Dist: seaborn ; extra == "analytics"
|
|
51
|
+
Requires-Dist: sqlalchemy
|
|
52
|
+
Requires-Dist: streamlit (>=1.32.2,<2.0.0) ; extra == "app"
|
|
53
|
+
Requires-Dist: uvicorn ; extra == "fastapi"
|
|
54
|
+
Description-Content-Type: text/markdown
|
|
55
|
+
|
|
56
|
+
# linkml-store
|
|
57
|
+
|
|
58
|
+
An AI-ready data management and integration platform. LinkML-Store
|
|
59
|
+
provides an abstraction layer over multiple different backends
|
|
60
|
+
(including DuckDB, MongoDB, and local filesystems), allowing for
|
|
61
|
+
common query, index, and storage operations.
|
|
62
|
+
|
|
63
|
+
For full documentation, see [https://linkml.io/linkml-store/](https://linkml.io/linkml-store/)
|
|
64
|
+
|
|
65
|
+
__Warning__ LinkML-Store is still undergoing changes and refactoring,
|
|
66
|
+
APIs and command line options are subject to change!
|
|
67
|
+
|
|
68
|
+
## Quick Start
|
|
69
|
+
|
|
70
|
+
Install, add data, query it:
|
|
71
|
+
|
|
72
|
+
```
|
|
73
|
+
pip install linkml-store[all]
|
|
74
|
+
linkml-store -d duckdb:///db/my.db -c persons insert data/*.json
|
|
75
|
+
linkml-store -d duckdb:///db/my.db -c persons query -w "occupation: Bricklayer"
|
|
76
|
+
```
|
|
77
|
+
|
|
78
|
+
Index it, search it:
|
|
79
|
+
|
|
80
|
+
```
|
|
81
|
+
linkml-store -d duckdb:///db/my.db -c persons index -t llm
|
|
82
|
+
linkml-store -d duckdb:///db/my.db -c persons search "all persons employed in construction"
|
|
83
|
+
```
|
|
84
|
+
|
|
85
|
+
Validate it:
|
|
86
|
+
|
|
87
|
+
```
|
|
88
|
+
linkml-store -d duckdb:///db/my.db -c persons validate
|
|
89
|
+
```
|
|
90
|
+
|
|
91
|
+
## Basic usage
|
|
92
|
+
|
|
93
|
+
* [Command Line](https://linkml.io/linkml-store/tutorials/Command-Line-Tutorial.html)
|
|
94
|
+
* [Python](https://linkml.io/linkml-store/tutorials/Python-Tutorial.html)
|
|
95
|
+
* API
|
|
96
|
+
* Streamlit applications
|
|
97
|
+
|
|
98
|
+
## Features
|
|
99
|
+
|
|
100
|
+
### Multiple Adapters
|
|
101
|
+
|
|
102
|
+
LinkML-Store is designed to work with multiple backends, giving a common abstraction layer
|
|
103
|
+
|
|
104
|
+
* [MongoDB](https://linkml.io/linkml-store/how-to/Use-MongoDB.html)
|
|
105
|
+
* [DuckDB](https://linkml.io/linkml-store/tutorials/Python-Tutorial.html)
|
|
106
|
+
* [Solr](https://linkml.io/linkml-store/how-to/Query-Solr-using-CLI.html)
|
|
107
|
+
* Filesystem
|
|
108
|
+
|
|
109
|
+
Coming soon: any RDBMS, any triplestore, Neo4J, HDF5-based stores, ChromaDB/Vector dbs ...
|
|
110
|
+
|
|
111
|
+
The intent is to give a union of all features of each backend. For
|
|
112
|
+
example, analytic faceted queries are provided for *all* backends, not
|
|
113
|
+
just Solr.
|
|
114
|
+
|
|
115
|
+
### Composable indexes
|
|
116
|
+
|
|
117
|
+
Many backends come with their own indexing and search
|
|
118
|
+
schemes. Classically this was Lucene-based indexes, now it is semantic
|
|
119
|
+
search using LLM embeddings.
|
|
120
|
+
|
|
121
|
+
LinkML store treats indexing as an orthogonal concern - you can
|
|
122
|
+
compose different indexing schemes with different backends. You don't
|
|
123
|
+
need to have a vector database to run embedding search!
|
|
124
|
+
|
|
125
|
+
See [How to Use-Semantic-Search](https://linkml.io/linkml-store/how-to/Use-Semantic-Search.html)
|
|
126
|
+
|
|
127
|
+
### Use with LLMs
|
|
128
|
+
|
|
129
|
+
TODO - docs
|
|
130
|
+
|
|
131
|
+
### Validation
|
|
132
|
+
|
|
133
|
+
LinkML-Store is backed by [LinkML](https://linkml.io), which allows
|
|
134
|
+
for powerful expressive structural and semantic constraints.
|
|
135
|
+
|
|
136
|
+
See [Indexing JSON](https://linkml.io/linkml-store/how-to/Index-Phenopackets.html)
|
|
137
|
+
|
|
138
|
+
and [Referential Integrity](https://linkml.io/linkml-store/how-to/Check-Referential-Integrity.html)
|
|
139
|
+
|
|
140
|
+
## Web API
|
|
141
|
+
|
|
142
|
+
There is a preliminary API following HATEOAS principles implemented using FastAPI.
|
|
143
|
+
|
|
144
|
+
To start you should first create a config file, e.g. `db/conf.yaml`:
|
|
145
|
+
|
|
146
|
+
Then run:
|
|
147
|
+
|
|
148
|
+
```
|
|
149
|
+
export LINKML_STORE_CONFIG=./db/conf.yaml
|
|
150
|
+
make api
|
|
151
|
+
```
|
|
152
|
+
|
|
153
|
+
The API returns links as well as data objects, it's recommended to use a Chrome plugin for JSON viewing
|
|
154
|
+
for exploring the API. TODO: add docs here.
|
|
155
|
+
|
|
156
|
+
The main endpoints are:
|
|
157
|
+
|
|
158
|
+
* `http://localhost:8000/` - the root of the API
|
|
159
|
+
* `http://localhost:8000/pages/` - browse the API via HTML
|
|
160
|
+
* `http://localhost:8000/docs` - the Swagger UI
|
|
161
|
+
|
|
162
|
+
## Streamlit app
|
|
163
|
+
|
|
164
|
+
```
|
|
165
|
+
make app
|
|
166
|
+
```
|
|
167
|
+
|
|
168
|
+
## Background
|
|
169
|
+
|
|
170
|
+
See [these slides](https://docs.google.com/presentation/d/e/2PACX-1vSgtWUNUW0qNO_ZhMAGQ6fYhlXZJjBNMYT0OiZz8DDx8oj7iG9KofRs6SeaMXBBOICGknoyMG2zaHnm/embed?start=false&loop=false&delayms=3000) for more details
|
|
171
|
+
|
|
@@ -0,0 +1,115 @@
|
|
|
1
|
+
# linkml-store
|
|
2
|
+
|
|
3
|
+
An AI-ready data management and integration platform. LinkML-Store
|
|
4
|
+
provides an abstraction layer over multiple different backends
|
|
5
|
+
(including DuckDB, MongoDB, and local filesystems), allowing for
|
|
6
|
+
common query, index, and storage operations.
|
|
7
|
+
|
|
8
|
+
For full documentation, see [https://linkml.io/linkml-store/](https://linkml.io/linkml-store/)
|
|
9
|
+
|
|
10
|
+
__Warning__ LinkML-Store is still undergoing changes and refactoring,
|
|
11
|
+
APIs and command line options are subject to change!
|
|
12
|
+
|
|
13
|
+
## Quick Start
|
|
14
|
+
|
|
15
|
+
Install, add data, query it:
|
|
16
|
+
|
|
17
|
+
```
|
|
18
|
+
pip install linkml-store[all]
|
|
19
|
+
linkml-store -d duckdb:///db/my.db -c persons insert data/*.json
|
|
20
|
+
linkml-store -d duckdb:///db/my.db -c persons query -w "occupation: Bricklayer"
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Index it, search it:
|
|
24
|
+
|
|
25
|
+
```
|
|
26
|
+
linkml-store -d duckdb:///db/my.db -c persons index -t llm
|
|
27
|
+
linkml-store -d duckdb:///db/my.db -c persons search "all persons employed in construction"
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Validate it:
|
|
31
|
+
|
|
32
|
+
```
|
|
33
|
+
linkml-store -d duckdb:///db/my.db -c persons validate
|
|
34
|
+
```
|
|
35
|
+
|
|
36
|
+
## Basic usage
|
|
37
|
+
|
|
38
|
+
* [Command Line](https://linkml.io/linkml-store/tutorials/Command-Line-Tutorial.html)
|
|
39
|
+
* [Python](https://linkml.io/linkml-store/tutorials/Python-Tutorial.html)
|
|
40
|
+
* API
|
|
41
|
+
* Streamlit applications
|
|
42
|
+
|
|
43
|
+
## Features
|
|
44
|
+
|
|
45
|
+
### Multiple Adapters
|
|
46
|
+
|
|
47
|
+
LinkML-Store is designed to work with multiple backends, giving a common abstraction layer
|
|
48
|
+
|
|
49
|
+
* [MongoDB](https://linkml.io/linkml-store/how-to/Use-MongoDB.html)
|
|
50
|
+
* [DuckDB](https://linkml.io/linkml-store/tutorials/Python-Tutorial.html)
|
|
51
|
+
* [Solr](https://linkml.io/linkml-store/how-to/Query-Solr-using-CLI.html)
|
|
52
|
+
* Filesystem
|
|
53
|
+
|
|
54
|
+
Coming soon: any RDBMS, any triplestore, Neo4J, HDF5-based stores, ChromaDB/Vector dbs ...
|
|
55
|
+
|
|
56
|
+
The intent is to give a union of all features of each backend. For
|
|
57
|
+
example, analytic faceted queries are provided for *all* backends, not
|
|
58
|
+
just Solr.
|
|
59
|
+
|
|
60
|
+
### Composable indexes
|
|
61
|
+
|
|
62
|
+
Many backends come with their own indexing and search
|
|
63
|
+
schemes. Classically this was Lucene-based indexes, now it is semantic
|
|
64
|
+
search using LLM embeddings.
|
|
65
|
+
|
|
66
|
+
LinkML store treats indexing as an orthogonal concern - you can
|
|
67
|
+
compose different indexing schemes with different backends. You don't
|
|
68
|
+
need to have a vector database to run embedding search!
|
|
69
|
+
|
|
70
|
+
See [How to Use-Semantic-Search](https://linkml.io/linkml-store/how-to/Use-Semantic-Search.html)
|
|
71
|
+
|
|
72
|
+
### Use with LLMs
|
|
73
|
+
|
|
74
|
+
TODO - docs
|
|
75
|
+
|
|
76
|
+
### Validation
|
|
77
|
+
|
|
78
|
+
LinkML-Store is backed by [LinkML](https://linkml.io), which allows
|
|
79
|
+
for powerful expressive structural and semantic constraints.
|
|
80
|
+
|
|
81
|
+
See [Indexing JSON](https://linkml.io/linkml-store/how-to/Index-Phenopackets.html)
|
|
82
|
+
|
|
83
|
+
and [Referential Integrity](https://linkml.io/linkml-store/how-to/Check-Referential-Integrity.html)
|
|
84
|
+
|
|
85
|
+
## Web API
|
|
86
|
+
|
|
87
|
+
There is a preliminary API following HATEOAS principles implemented using FastAPI.
|
|
88
|
+
|
|
89
|
+
To start you should first create a config file, e.g. `db/conf.yaml`:
|
|
90
|
+
|
|
91
|
+
Then run:
|
|
92
|
+
|
|
93
|
+
```
|
|
94
|
+
export LINKML_STORE_CONFIG=./db/conf.yaml
|
|
95
|
+
make api
|
|
96
|
+
```
|
|
97
|
+
|
|
98
|
+
The API returns links as well as data objects, it's recommended to use a Chrome plugin for JSON viewing
|
|
99
|
+
for exploring the API. TODO: add docs here.
|
|
100
|
+
|
|
101
|
+
The main endpoints are:
|
|
102
|
+
|
|
103
|
+
* `http://localhost:8000/` - the root of the API
|
|
104
|
+
* `http://localhost:8000/pages/` - browse the API via HTML
|
|
105
|
+
* `http://localhost:8000/docs` - the Swagger UI
|
|
106
|
+
|
|
107
|
+
## Streamlit app
|
|
108
|
+
|
|
109
|
+
```
|
|
110
|
+
make app
|
|
111
|
+
```
|
|
112
|
+
|
|
113
|
+
## Background
|
|
114
|
+
|
|
115
|
+
See [these slides](https://docs.google.com/presentation/d/e/2PACX-1vSgtWUNUW0qNO_ZhMAGQ6fYhlXZJjBNMYT0OiZz8DDx8oj7iG9KofRs6SeaMXBBOICGknoyMG2zaHnm/embed?start=false&loop=false&delayms=3000) for more details
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
[tool.poetry]
|
|
2
2
|
name = "linkml-store"
|
|
3
|
-
version = "0.1.
|
|
3
|
+
version = "0.1.11"
|
|
4
4
|
description = "linkml-store"
|
|
5
5
|
authors = ["Author 1 <author@org.org>"]
|
|
6
6
|
license = "MIT"
|
|
@@ -10,7 +10,7 @@ readme = "README.md"
|
|
|
10
10
|
python = "^3.9, !=3.9.7"
|
|
11
11
|
click = "*"
|
|
12
12
|
pydantic = "^2.0.0"
|
|
13
|
-
linkml-runtime = "
|
|
13
|
+
linkml-runtime = ">=1.8.0"
|
|
14
14
|
streamlit = { version = "^1.32.2", optional = true }
|
|
15
15
|
sqlalchemy = "*"
|
|
16
16
|
duckdb = "^0.10.1"
|
|
@@ -25,11 +25,15 @@ pymongo = { version="*", optional = true }
|
|
|
25
25
|
chromadb = { version="*", optional = true }
|
|
26
26
|
pyarrow = { version="*", optional = true }
|
|
27
27
|
h5py = { version="*", optional = true }
|
|
28
|
-
linkml = { version="
|
|
28
|
+
linkml = { version=">=1.8.0", optional = true }
|
|
29
29
|
linkml_map = { version="*", optional = true }
|
|
30
|
+
linkml_renderer = { version="*", optional = true }
|
|
31
|
+
frictionless = { version="*", optional = true }
|
|
30
32
|
pandas = ">=2.2.1"
|
|
31
33
|
jinja2 = "^3.1.4"
|
|
32
34
|
jsonlines = "^4.0.0"
|
|
35
|
+
fastapi = { version="*", optional = true }
|
|
36
|
+
uvicorn = { version="*", optional = true }
|
|
33
37
|
|
|
34
38
|
[tool.poetry.group.dev.dependencies]
|
|
35
39
|
pytest = {version = ">=7.1.2"}
|
|
@@ -46,6 +50,7 @@ nbsphinx = "*"
|
|
|
46
50
|
jupyter = "*"
|
|
47
51
|
jupysql = "*"
|
|
48
52
|
papermill = "*"
|
|
53
|
+
nbdime = "*"
|
|
49
54
|
|
|
50
55
|
[tool.poetry.group.tests.dependencies]
|
|
51
56
|
pytest = "^7.4.0"
|
|
@@ -66,9 +71,13 @@ h5py = ["h5py"]
|
|
|
66
71
|
pyarrow = ["pyarrow"]
|
|
67
72
|
validation = ["linkml"]
|
|
68
73
|
map = ["linkml_map"]
|
|
74
|
+
renderer = ["linkml_renderer"]
|
|
75
|
+
fastapi = ["fastapi", "uvicorn"]
|
|
76
|
+
frictionless = ["frictionless"]
|
|
69
77
|
|
|
70
78
|
[tool.poetry.scripts]
|
|
71
79
|
linkml-store = "linkml_store.cli:cli"
|
|
80
|
+
linkml-store-api = "linkml_store.webapi.main:start"
|
|
72
81
|
|
|
73
82
|
[tool.poetry-dynamic-versioning]
|
|
74
83
|
enable = false
|
|
@@ -98,7 +98,7 @@ class Client:
|
|
|
98
98
|
"""
|
|
99
99
|
return self.metadata.base_dir
|
|
100
100
|
|
|
101
|
-
def from_config(self, config: Union[ClientConfig, str, Path], base_dir=None, **kwargs):
|
|
101
|
+
def from_config(self, config: Union[ClientConfig, dict, str, Path], base_dir=None, **kwargs):
|
|
102
102
|
"""
|
|
103
103
|
Create a client from a configuration.
|
|
104
104
|
|
|
@@ -118,11 +118,13 @@ class Client:
|
|
|
118
118
|
:return:
|
|
119
119
|
|
|
120
120
|
"""
|
|
121
|
+
if isinstance(config, dict):
|
|
122
|
+
config = ClientConfig(**config)
|
|
121
123
|
if isinstance(config, Path):
|
|
122
124
|
config = str(config)
|
|
123
125
|
if isinstance(config, str):
|
|
124
|
-
if not base_dir:
|
|
125
|
-
|
|
126
|
+
# if not base_dir:
|
|
127
|
+
# base_dir = Path(config).parent
|
|
126
128
|
parsed_obj = yaml.safe_load(open(config))
|
|
127
129
|
config = ClientConfig(**parsed_obj)
|
|
128
130
|
self.metadata = config
|
|
@@ -133,8 +135,15 @@ class Client:
|
|
|
133
135
|
|
|
134
136
|
def _initialize_databases(self, **kwargs):
|
|
135
137
|
for name, db_config in self.metadata.databases.items():
|
|
136
|
-
|
|
138
|
+
base_dir = self.base_dir
|
|
139
|
+
logger.info(f"Initializing database: {name}, base_dir: {base_dir}")
|
|
140
|
+
if not base_dir:
|
|
141
|
+
base_dir = Path.cwd()
|
|
142
|
+
logger.info(f"Using current working directory: {base_dir}")
|
|
143
|
+
handle = db_config.handle.format(base_dir=base_dir)
|
|
137
144
|
db_config.handle = handle
|
|
145
|
+
if db_config.schema_location:
|
|
146
|
+
db_config.schema_location = db_config.schema_location.format(base_dir=base_dir)
|
|
138
147
|
db = self.attach_database(handle, alias=name, **kwargs)
|
|
139
148
|
db.from_config(db_config)
|
|
140
149
|
|
|
@@ -233,7 +242,7 @@ class Client:
|
|
|
233
242
|
Return all attached databases
|
|
234
243
|
|
|
235
244
|
Examples
|
|
236
|
-
|
|
245
|
+
|
|
237
246
|
>>> client = Client()
|
|
238
247
|
>>> _ = client.attach_database("duckdb", alias="test1")
|
|
239
248
|
>>> _ = client.attach_database("duckdb", alias="test2")
|
|
@@ -259,25 +268,81 @@ class Client:
|
|
|
259
268
|
"""
|
|
260
269
|
Drop a database.
|
|
261
270
|
|
|
271
|
+
Example (in-memory):
|
|
272
|
+
|
|
273
|
+
>>> client = Client()
|
|
274
|
+
>>> db1 = client.attach_database("duckdb", alias="test1")
|
|
275
|
+
>>> db2 = client.attach_database("duckdb", alias="test2")
|
|
276
|
+
>>> len(client.databases)
|
|
277
|
+
2
|
|
278
|
+
>>> client.drop_database("test1")
|
|
279
|
+
>>> len(client.databases)
|
|
280
|
+
1
|
|
281
|
+
|
|
282
|
+
Databases that persist on disk:
|
|
283
|
+
|
|
284
|
+
>>> client = Client()
|
|
285
|
+
>>> path = Path("tmp/test.db")
|
|
286
|
+
>>> path.parent.mkdir(parents=True, exist_ok=True)
|
|
287
|
+
>>> db = client.attach_database(f"duckdb:///{path}", alias="test")
|
|
288
|
+
>>> len(client.databases)
|
|
289
|
+
1
|
|
290
|
+
>>> db.store({"persons": [{"id": "P1", "name": "John"}]})
|
|
291
|
+
>>> db.commit()
|
|
292
|
+
>>> Path("tmp/test.db").exists()
|
|
293
|
+
True
|
|
294
|
+
>>> client.drop_database("test")
|
|
295
|
+
>>> len(client.databases)
|
|
296
|
+
0
|
|
297
|
+
>>> Path("tmp/test.db").exists()
|
|
298
|
+
False
|
|
299
|
+
|
|
300
|
+
Dropping a non-existent database:
|
|
301
|
+
|
|
302
|
+
>>> client = Client()
|
|
303
|
+
>>> client.drop_database("duckdb:///tmp/made-up1", missing_ok=True)
|
|
304
|
+
>>> client.drop_database("duckdb:///tmp/made-up2", missing_ok=False)
|
|
305
|
+
Traceback (most recent call last):
|
|
306
|
+
...
|
|
307
|
+
ValueError: Database duckdb:///tmp/made-up2 not found
|
|
308
|
+
|
|
262
309
|
:param name:
|
|
263
310
|
:param missing_ok:
|
|
264
311
|
:return:
|
|
265
312
|
"""
|
|
266
|
-
if
|
|
267
|
-
|
|
268
|
-
|
|
269
|
-
|
|
313
|
+
if self._databases:
|
|
314
|
+
if name in self._databases:
|
|
315
|
+
db = self._databases[name]
|
|
316
|
+
db.drop(**kwargs)
|
|
317
|
+
del self._databases[name]
|
|
318
|
+
else:
|
|
319
|
+
if not missing_ok:
|
|
320
|
+
raise ValueError(f"Database {name} not found")
|
|
270
321
|
else:
|
|
271
|
-
|
|
272
|
-
|
|
322
|
+
db = self.get_database(name, create_if_not_exists=True)
|
|
323
|
+
db.drop(**kwargs)
|
|
273
324
|
|
|
274
325
|
def drop_all_databases(self, **kwargs):
|
|
275
326
|
"""
|
|
276
327
|
Drop all databases.
|
|
277
328
|
|
|
329
|
+
Example (in-memory):
|
|
330
|
+
|
|
331
|
+
>>> client = Client()
|
|
332
|
+
>>> db1 = client.attach_database("duckdb", alias="test1")
|
|
333
|
+
>>> assert "test1" in client.databases
|
|
334
|
+
>>> db2 = client.attach_database("duckdb", alias="test2")
|
|
335
|
+
>>> assert "test2" in client.databases
|
|
336
|
+
>>> client.drop_all_databases()
|
|
337
|
+
>>> len(client.databases)
|
|
338
|
+
0
|
|
339
|
+
|
|
340
|
+
|
|
278
341
|
:param missing_ok:
|
|
279
342
|
:return:
|
|
280
343
|
"""
|
|
344
|
+
if not self._databases:
|
|
345
|
+
return
|
|
281
346
|
for name in list(self._databases.keys()):
|
|
282
347
|
self.drop_database(name, missing_ok=False, **kwargs)
|
|
283
348
|
self._databases = {}
|