mirror of
https://github.com/p2p-ld/nwb-linkml.git
synced 2024-11-10 00:34:29 +00:00
figuring out the strategy here...
- added linkml_meta classvar to store additional linkml properties if needed - injecting path field to metaclass - sketch of doing a queue-based read - prune datasets & example allen institute data
This commit is contained in:
parent
321740f674
commit
40984a6582
10 changed files with 607 additions and 355 deletions
|
@ -39,7 +39,8 @@ intersphinx_mapping = {
|
||||||
'matplotlib': ('https://matplotlib.org/stable/', None),
|
'matplotlib': ('https://matplotlib.org/stable/', None),
|
||||||
'numpy': ('https://numpy.org/doc/stable/', None),
|
'numpy': ('https://numpy.org/doc/stable/', None),
|
||||||
'pandas': ('https://pandas.pydata.org/docs/', None),
|
'pandas': ('https://pandas.pydata.org/docs/', None),
|
||||||
'pydantic': ('https://docs.pydantic.dev/latest/', None)
|
'pydantic': ('https://docs.pydantic.dev/latest/', None),
|
||||||
|
'h5py': ('https://docs.h5py.org/en/stable/', None)
|
||||||
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
374
nwb_linkml/poetry.lock
generated
374
nwb_linkml/poetry.lock
generated
|
@ -295,13 +295,13 @@ yaml = ["PyYAML (>=3.10)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "curies"
|
name = "curies"
|
||||||
version = "0.6.0"
|
version = "0.6.3"
|
||||||
description = "Idiomatic conversion between URIs and compact URIs (CURIEs)."
|
description = "Idiomatic conversion between URIs and compact URIs (CURIEs)."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "curies-0.6.0-py3-none-any.whl", hash = "sha256:0bf79e2176b2e44dee7fefadcd1f2d69e643fea124dc4a8d0dbf47ca5e1589f2"},
|
{file = "curies-0.6.3-py3-none-any.whl", hash = "sha256:fb4e99b011f34fb61f7aa38e0bb32c6c6c529c252d27ad2c8a7031687c6894ea"},
|
||||||
{file = "curies-0.6.0.tar.gz", hash = "sha256:a31533ae9caeec332f9bb33e21366ab7ec32437c5f347fc9d85aa77cc48093cc"},
|
{file = "curies-0.6.3.tar.gz", hash = "sha256:37f4763c387a674adcfa5e93d222315d646647a2df198a60382ff877b72963df"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -397,17 +397,6 @@ files = [
|
||||||
{file = "dash_table-5.0.0.tar.gz", hash = "sha256:18624d693d4c8ef2ddec99a6f167593437a7ea0bf153aa20f318c170c5bc7308"},
|
{file = "dash_table-5.0.0.tar.gz", hash = "sha256:18624d693d4c8ef2ddec99a6f167593437a7ea0bf153aa20f318c170c5bc7308"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
|
||||||
name = "decorator"
|
|
||||||
version = "5.1.1"
|
|
||||||
description = "Decorators for Humans"
|
|
||||||
optional = false
|
|
||||||
python-versions = ">=3.5"
|
|
||||||
files = [
|
|
||||||
{file = "decorator-5.1.1-py3-none-any.whl", hash = "sha256:b8c3f85900b9dc423225913c5aace94729fe1fa9763b38939a95226f02d37186"},
|
|
||||||
{file = "decorator-5.1.1.tar.gz", hash = "sha256:637996211036b6385ef91435e4fae22989472f9d571faba8927ba8253acbc330"},
|
|
||||||
]
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "deprecated"
|
name = "deprecated"
|
||||||
version = "1.2.14"
|
version = "1.2.14"
|
||||||
|
@ -789,20 +778,17 @@ jsonpointer = ">=1.9"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonpath-ng"
|
name = "jsonpath-ng"
|
||||||
version = "1.5.3"
|
version = "1.6.0"
|
||||||
description = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming."
|
description = "A final implementation of JSONPath for Python that aims to be standard compliant, including arithmetic and binary comparison operators and providing clear AST for metaprogramming."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = "*"
|
python-versions = "*"
|
||||||
files = [
|
files = [
|
||||||
{file = "jsonpath-ng-1.5.3.tar.gz", hash = "sha256:a273b182a82c1256daab86a313b937059261b5c5f8c4fa3fc38b882b344dd567"},
|
{file = "jsonpath-ng-1.6.0.tar.gz", hash = "sha256:5483f8e9d74c39c9abfab554c070ae783c1c8cbadf5df60d561bc705ac68a07e"},
|
||||||
{file = "jsonpath_ng-1.5.3-py2-none-any.whl", hash = "sha256:f75b95dbecb8a0f3b86fd2ead21c2b022c3f5770957492b9b6196ecccfeb10aa"},
|
{file = "jsonpath_ng-1.6.0-py3-none-any.whl", hash = "sha256:6fd04833412c4b3d9299edf369542f5e67095ca84efa17cbb7f06a34958adc9f"},
|
||||||
{file = "jsonpath_ng-1.5.3-py3-none-any.whl", hash = "sha256:292a93569d74029ba75ac2dc3d3630fc0e17b2df26119a165fa1d498ca47bf65"},
|
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
decorator = "*"
|
|
||||||
ply = "*"
|
ply = "*"
|
||||||
six = "*"
|
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonpointer"
|
name = "jsonpointer"
|
||||||
|
@ -817,13 +803,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "jsonschema"
|
name = "jsonschema"
|
||||||
version = "4.19.0"
|
version = "4.19.1"
|
||||||
description = "An implementation of JSON Schema validation for Python"
|
description = "An implementation of JSON Schema validation for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "jsonschema-4.19.0-py3-none-any.whl", hash = "sha256:043dc26a3845ff09d20e4420d6012a9c91c9aa8999fa184e7efcfeccb41e32cb"},
|
{file = "jsonschema-4.19.1-py3-none-any.whl", hash = "sha256:cd5f1f9ed9444e554b38ba003af06c0a8c2868131e56bfbef0550fb450c0330e"},
|
||||||
{file = "jsonschema-4.19.0.tar.gz", hash = "sha256:6e1e7569ac13be8139b2dd2c21a55d350066ee3f80df06c608b398cdc6f30e8f"},
|
{file = "jsonschema-4.19.1.tar.gz", hash = "sha256:ec84cc37cfa703ef7cd4928db24f9cb31428a5d0fa77747b8b51a847458e0bbf"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -1035,13 +1021,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "nest-asyncio"
|
name = "nest-asyncio"
|
||||||
version = "1.5.7"
|
version = "1.5.8"
|
||||||
description = "Patch asyncio to allow nested event loops"
|
description = "Patch asyncio to allow nested event loops"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.5"
|
python-versions = ">=3.5"
|
||||||
files = [
|
files = [
|
||||||
{file = "nest_asyncio-1.5.7-py3-none-any.whl", hash = "sha256:5301c82941b550b3123a1ea772ba9a1c80bad3a182be8c1a5ae6ad3be57a9657"},
|
{file = "nest_asyncio-1.5.8-py3-none-any.whl", hash = "sha256:accda7a339a70599cb08f9dd09a67e0c2ef8d8d6f4c07f96ab203f2ae254e48d"},
|
||||||
{file = "nest_asyncio-1.5.7.tar.gz", hash = "sha256:6a80f7b98f24d9083ed24608977c09dd608d83f91cccc24c9d2cba6d10e01c10"},
|
{file = "nest_asyncio-1.5.8.tar.gz", hash = "sha256:25aa2ca0d2a5b5531956b9e273b45cf664cae2b145101d73b86b199978d48fdb"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -1170,13 +1156,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "plotly"
|
name = "plotly"
|
||||||
version = "5.16.1"
|
version = "5.17.0"
|
||||||
description = "An open-source, interactive data visualization library for Python"
|
description = "An open-source, interactive data visualization library for Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.6"
|
python-versions = ">=3.6"
|
||||||
files = [
|
files = [
|
||||||
{file = "plotly-5.16.1-py2.py3-none-any.whl", hash = "sha256:19cc34f339acd4e624177806c14df22f388f23fb70658b03aad959a0e650a0dc"},
|
{file = "plotly-5.17.0-py2.py3-none-any.whl", hash = "sha256:7c84cdf11da162423da957bb093287134f2d6f170eb9a74f1459f825892247c3"},
|
||||||
{file = "plotly-5.16.1.tar.gz", hash = "sha256:295ac25edeb18c893abb71dcadcea075b78fd6fdf07cee4217a4e1009667925b"},
|
{file = "plotly-5.17.0.tar.gz", hash = "sha256:290d796bf7bab87aad184fe24b86096234c4c95dcca6ecbca02d02bdf17d3d97"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -1486,13 +1472,13 @@ shexjsg = ">=0.8.1"
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "pytest"
|
name = "pytest"
|
||||||
version = "7.4.1"
|
version = "7.4.2"
|
||||||
description = "pytest: simple powerful testing with Python"
|
description = "pytest: simple powerful testing with Python"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "pytest-7.4.1-py3-none-any.whl", hash = "sha256:460c9a59b14e27c602eb5ece2e47bec99dc5fc5f6513cf924a7d03a578991b1f"},
|
{file = "pytest-7.4.2-py3-none-any.whl", hash = "sha256:1d881c6124e08ff0a1bb75ba3ec0bfd8b5354a01c194ddd5a0a870a48d99b002"},
|
||||||
{file = "pytest-7.4.1.tar.gz", hash = "sha256:2f2301e797521b23e4d2585a0a3d7b5e50fdddaaf7e7d6773ea26ddb17c213ab"},
|
{file = "pytest-7.4.2.tar.gz", hash = "sha256:a766259cfab564a2ad52cb1aae1b881a75c3eb7e34ca3779697c23ed47c47069"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -1816,13 +1802,13 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rich"
|
name = "rich"
|
||||||
version = "13.5.2"
|
version = "13.5.3"
|
||||||
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
|
description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7.0"
|
python-versions = ">=3.7.0"
|
||||||
files = [
|
files = [
|
||||||
{file = "rich-13.5.2-py3-none-any.whl", hash = "sha256:146a90b3b6b47cac4a73c12866a499e9817426423f57c5a66949c086191a8808"},
|
{file = "rich-13.5.3-py3-none-any.whl", hash = "sha256:9257b468badc3d347e146a4faa268ff229039d4c2d176ab0cffb4c4fbc73d5d9"},
|
||||||
{file = "rich-13.5.2.tar.gz", hash = "sha256:fb9d6c0a0f643c99eed3875b5377a184132ba9be4d61516a55273d3554d75a39"},
|
{file = "rich-13.5.3.tar.gz", hash = "sha256:87b43e0543149efa1253f485cd845bb7ee54df16c9617b8a893650ab84b4acb6"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -1834,108 +1820,108 @@ jupyter = ["ipywidgets (>=7.5.1,<9)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "rpds-py"
|
name = "rpds-py"
|
||||||
version = "0.10.2"
|
version = "0.10.3"
|
||||||
description = "Python bindings to Rust's persistent data structures (rpds)"
|
description = "Python bindings to Rust's persistent data structures (rpds)"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "rpds_py-0.10.2-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:9f00d54b18dd837f1431d66b076737deb7c29ce3ebb8412ceaf44d5e1954ac0c"},
|
{file = "rpds_py-0.10.3-cp310-cp310-macosx_10_7_x86_64.whl", hash = "sha256:485747ee62da83366a44fbba963c5fe017860ad408ccd6cd99aa66ea80d32b2e"},
|
||||||
{file = "rpds_py-0.10.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f4d561f4728f825e3b793a53064b606ca0b6fc264f67d09e54af452aafc5b82"},
|
{file = "rpds_py-0.10.3-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c55f9821f88e8bee4b7a72c82cfb5ecd22b6aad04033334f33c329b29bfa4da0"},
|
||||||
{file = "rpds_py-0.10.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:013d6c784150d10236a74b4094a79d96a256b814457e388fc5a4ba9efe24c402"},
|
{file = "rpds_py-0.10.3-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d3b52a67ac66a3a64a7e710ba629f62d1e26ca0504c29ee8cbd99b97df7079a8"},
|
||||||
{file = "rpds_py-0.10.2-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:bd1142d22fdb183a0fff66d79134bf644401437fed874f81066d314c67ee193c"},
|
{file = "rpds_py-0.10.3-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:3aed39db2f0ace76faa94f465d4234aac72e2f32b009f15da6492a561b3bbebd"},
|
||||||
{file = "rpds_py-0.10.2-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4a0536ed2b9297c75104e1a3da330828ba1b2639fa53b38d396f98bf7e3c68df"},
|
{file = "rpds_py-0.10.3-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:271c360fdc464fe6a75f13ea0c08ddf71a321f4c55fc20a3fe62ea3ef09df7d9"},
|
||||||
{file = "rpds_py-0.10.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:41bd430b7b63aa802c02964e331ac0b177148fef5f807d2c90d05ce71a52b4d4"},
|
{file = "rpds_py-0.10.3-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ef5fddfb264e89c435be4adb3953cef5d2936fdeb4463b4161a6ba2f22e7b740"},
|
||||||
{file = "rpds_py-0.10.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e8474f7233fe1949ce4e03bea698a600c2d5d6b51dab6d6e6336dbe69acf23e"},
|
{file = "rpds_py-0.10.3-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a771417c9c06c56c9d53d11a5b084d1de75de82978e23c544270ab25e7c066ff"},
|
||||||
{file = "rpds_py-0.10.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d9d7efaad48b859053b90dedd69bc92f2095084251e732e4c57ac9726bcb1e64"},
|
{file = "rpds_py-0.10.3-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:52b5cbc0469328e58180021138207e6ec91d7ca2e037d3549cc9e34e2187330a"},
|
||||||
{file = "rpds_py-0.10.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5612b0b1de8d5114520094bd5fc3d04eb8af6f3e10d48ef05b7c8e77c1fd9545"},
|
{file = "rpds_py-0.10.3-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:6ac3fefb0d168c7c6cab24fdfc80ec62cd2b4dfd9e65b84bdceb1cb01d385c33"},
|
||||||
{file = "rpds_py-0.10.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:5d5eaf988951f6ecb6854ca3300b87123599c711183c83da7ce39717a7cbdbce"},
|
{file = "rpds_py-0.10.3-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:8d54bbdf5d56e2c8cf81a1857250f3ea132de77af543d0ba5dce667183b61fec"},
|
||||||
{file = "rpds_py-0.10.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:75c8766734ac0053e1d683567e65e85306c4ec62631b0591caeb287ac8f72e08"},
|
{file = "rpds_py-0.10.3-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:cd2163f42868865597d89399a01aa33b7594ce8e2c4a28503127c81a2f17784e"},
|
||||||
{file = "rpds_py-0.10.2-cp310-none-win32.whl", hash = "sha256:8de9b88f0cbac73cfed34220d13c57849e62a7099a714b929142425e926d223a"},
|
{file = "rpds_py-0.10.3-cp310-none-win32.whl", hash = "sha256:ea93163472db26ac6043e8f7f93a05d9b59e0505c760da2a3cd22c7dd7111391"},
|
||||||
{file = "rpds_py-0.10.2-cp310-none-win_amd64.whl", hash = "sha256:2275f1a022e2383da5d2d101fe11ccdcbae799148c4b83260a4b9309fa3e1fc2"},
|
{file = "rpds_py-0.10.3-cp310-none-win_amd64.whl", hash = "sha256:7cd020b1fb41e3ab7716d4d2c3972d4588fdfbab9bfbbb64acc7078eccef8860"},
|
||||||
{file = "rpds_py-0.10.2-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:dd91a7d7a9ce7f4983097c91ce211f3e5569cc21caa16f2692298a07e396f82b"},
|
{file = "rpds_py-0.10.3-cp311-cp311-macosx_10_7_x86_64.whl", hash = "sha256:1d9b5ee46dcb498fa3e46d4dfabcb531e1f2e76b477e0d99ef114f17bbd38453"},
|
||||||
{file = "rpds_py-0.10.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:e82b4a70cc67094f3f3fd77579702f48fcf1de7bdc67d79b8f1e24d089a6162c"},
|
{file = "rpds_py-0.10.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:563646d74a4b4456d0cf3b714ca522e725243c603e8254ad85c3b59b7c0c4bf0"},
|
||||||
{file = "rpds_py-0.10.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e281b71922208e00886e4b7ffbfcf27874486364f177418ab676f102130e7ec9"},
|
{file = "rpds_py-0.10.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e626b864725680cd3904414d72e7b0bd81c0e5b2b53a5b30b4273034253bb41f"},
|
||||||
{file = "rpds_py-0.10.2-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b3eb1a0d2b6d232d1bcdfc3fcc5f7b004ab3fbd9203011a3172f051d4527c0b6"},
|
{file = "rpds_py-0.10.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:485301ee56ce87a51ccb182a4b180d852c5cb2b3cb3a82f7d4714b4141119d8c"},
|
||||||
{file = "rpds_py-0.10.2-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:02945ae38fd78efc40900f509890de84cfd5ffe2cd2939eeb3a8800dc68b87cb"},
|
{file = "rpds_py-0.10.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:42f712b4668831c0cd85e0a5b5a308700fe068e37dcd24c0062904c4e372b093"},
|
||||||
{file = "rpds_py-0.10.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ccfb77f6dc8abffa6f1c7e3975ed9070a41ce5fcc11154d2bead8c1baa940f09"},
|
{file = "rpds_py-0.10.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6c9141af27a4e5819d74d67d227d5047a20fa3c7d4d9df43037a955b4c748ec5"},
|
||||||
{file = "rpds_py-0.10.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:af52078719209bef33e38131486fd784832dd8d1dc9b85f00a44f6e7437dd021"},
|
{file = "rpds_py-0.10.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ef750a20de1b65657a1425f77c525b0183eac63fe7b8f5ac0dd16f3668d3e64f"},
|
||||||
{file = "rpds_py-0.10.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:56ba7c1100ed079527f2b995bf5486a2e557e6d5b733c52e8947476338815b69"},
|
{file = "rpds_py-0.10.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e1a0ffc39f51aa5f5c22114a8f1906b3c17eba68c5babb86c5f77d8b1bba14d1"},
|
||||||
{file = "rpds_py-0.10.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:899b03a3be785a7e1ff84b237da71f0efa2f021512f147dd34ffdf7aa82cb678"},
|
{file = "rpds_py-0.10.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:f4c179a7aeae10ddf44c6bac87938134c1379c49c884529f090f9bf05566c836"},
|
||||||
{file = "rpds_py-0.10.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:22e6de18f00583f06928cc8d0993104ecc62f7c6da6478db2255de89a30e45d1"},
|
{file = "rpds_py-0.10.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:176287bb998fd1e9846a9b666e240e58f8d3373e3bf87e7642f15af5405187b8"},
|
||||||
{file = "rpds_py-0.10.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:edd74b760a6bb950397e7a7bd2f38e6700f6525062650b1d77c6d851b82f02c2"},
|
{file = "rpds_py-0.10.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:6446002739ca29249f0beaaf067fcbc2b5aab4bc7ee8fb941bd194947ce19aff"},
|
||||||
{file = "rpds_py-0.10.2-cp311-none-win32.whl", hash = "sha256:18909093944727e068ebfc92e2e6ed1c4fa44135507c1c0555213ce211c53214"},
|
{file = "rpds_py-0.10.3-cp311-none-win32.whl", hash = "sha256:c7aed97f2e676561416c927b063802c8a6285e9b55e1b83213dfd99a8f4f9e48"},
|
||||||
{file = "rpds_py-0.10.2-cp311-none-win_amd64.whl", hash = "sha256:9568764e72d85cf7855ca78b48e07ed1be47bf230e2cea8dabda3c95f660b0ff"},
|
{file = "rpds_py-0.10.3-cp311-none-win_amd64.whl", hash = "sha256:8bd01ff4032abaed03f2db702fa9a61078bee37add0bd884a6190b05e63b028c"},
|
||||||
{file = "rpds_py-0.10.2-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:0fc625059b83695fbb4fc8b7a8b66fa94ff9c7b78c84fb9986cd53ff88a28d80"},
|
{file = "rpds_py-0.10.3-cp312-cp312-macosx_10_7_x86_64.whl", hash = "sha256:4cf0855a842c5b5c391dd32ca273b09e86abf8367572073bd1edfc52bc44446b"},
|
||||||
{file = "rpds_py-0.10.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c86231c66e4f422e7c13ea6200bb4048b3016c8bfd11b4fd0dabd04d2c8e3501"},
|
{file = "rpds_py-0.10.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:69b857a7d8bd4f5d6e0db4086da8c46309a26e8cefdfc778c0c5cc17d4b11e08"},
|
||||||
{file = "rpds_py-0.10.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:56777c57246e048908b550af9b81b0ec9cf804fd47cb7502ccd93238bd6025c2"},
|
{file = "rpds_py-0.10.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:975382d9aa90dc59253d6a83a5ca72e07f4ada3ae3d6c0575ced513db322b8ec"},
|
||||||
{file = "rpds_py-0.10.2-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a4cb372e22e9c879bd9a9cc9b20b7c1fbf30a605ac953da45ecec05d8a6e1c77"},
|
{file = "rpds_py-0.10.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:35fbd23c1c8732cde7a94abe7fb071ec173c2f58c0bd0d7e5b669fdfc80a2c7b"},
|
||||||
{file = "rpds_py-0.10.2-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aa3b3a43dabc4cc57a7800f526cbe03f71c69121e21b863fdf497b59b462b163"},
|
{file = "rpds_py-0.10.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:106af1653007cc569d5fbb5f08c6648a49fe4de74c2df814e234e282ebc06957"},
|
||||||
{file = "rpds_py-0.10.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:59d222086daa55421d599609b32d0ebe544e57654c4a0a1490c54a7ebaa67561"},
|
{file = "rpds_py-0.10.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ce5e7504db95b76fc89055c7f41e367eaadef5b1d059e27e1d6eabf2b55ca314"},
|
||||||
{file = "rpds_py-0.10.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:529aab727f54a937085184e7436e1d0e19975cf10115eda12d37a683e4ee5342"},
|
{file = "rpds_py-0.10.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5aca759ada6b1967fcfd4336dcf460d02a8a23e6abe06e90ea7881e5c22c4de6"},
|
||||||
{file = "rpds_py-0.10.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:43e9b1531d6a898bdf086acb75c41265c7ec4331267d7619148d407efc72bd24"},
|
{file = "rpds_py-0.10.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b5d4bdd697195f3876d134101c40c7d06d46c6ab25159ed5cbd44105c715278a"},
|
||||||
{file = "rpds_py-0.10.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:c2772bb95062e3f9774140205cd65d8997e39620715486cf5f843cf4ad8f744c"},
|
{file = "rpds_py-0.10.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a657250807b6efd19b28f5922520ae002a54cb43c2401e6f3d0230c352564d25"},
|
||||||
{file = "rpds_py-0.10.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ba1b28e44f611f3f2b436bd8290050a61db4b59a8e24be4465f44897936b3824"},
|
{file = "rpds_py-0.10.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:177c9dd834cdf4dc39c27436ade6fdf9fe81484758885f2d616d5d03c0a83bd2"},
|
||||||
{file = "rpds_py-0.10.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5aba767e64b494483ad60c4873bec78d16205a21f8247c99749bd990d9c846c2"},
|
{file = "rpds_py-0.10.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e22491d25f97199fc3581ad8dd8ce198d8c8fdb8dae80dea3512e1ce6d5fa99f"},
|
||||||
{file = "rpds_py-0.10.2-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:e1954f4b239d1a92081647eecfd51cbfd08ea16eb743b8af1cd0113258feea14"},
|
{file = "rpds_py-0.10.3-cp38-cp38-macosx_10_7_x86_64.whl", hash = "sha256:2f3e1867dd574014253b4b8f01ba443b9c914e61d45f3674e452a915d6e929a3"},
|
||||||
{file = "rpds_py-0.10.2-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:de4a2fd524993578fe093044f291b4b24aab134390030b3b9b5f87fd41ab7e75"},
|
{file = "rpds_py-0.10.3-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:c22211c165166de6683de8136229721f3d5c8606cc2c3d1562da9a3a5058049c"},
|
||||||
{file = "rpds_py-0.10.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e69737bd56006a86fd5a78b2b85447580a6138c930a75eb9ef39fe03d90782b1"},
|
{file = "rpds_py-0.10.3-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:40bc802a696887b14c002edd43c18082cb7b6f9ee8b838239b03b56574d97f71"},
|
||||||
{file = "rpds_py-0.10.2-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:f40abbcc0a7d9a8a80870af839d317e6932533f98682aabd977add6c53beeb23"},
|
{file = "rpds_py-0.10.3-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:5e271dd97c7bb8eefda5cca38cd0b0373a1fea50f71e8071376b46968582af9b"},
|
||||||
{file = "rpds_py-0.10.2-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:29ec8507664f94cc08457d98cfc41c3cdbddfa8952438e644177a29b04937876"},
|
{file = "rpds_py-0.10.3-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:95cde244e7195b2c07ec9b73fa4c5026d4a27233451485caa1cd0c1b55f26dbd"},
|
||||||
{file = "rpds_py-0.10.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:bcde80aefe7054fad6277762fb7e9d35c72ea479a485ae1bb14629c640987b30"},
|
{file = "rpds_py-0.10.3-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:08a80cf4884920863623a9ee9a285ee04cef57ebedc1cc87b3e3e0f24c8acfe5"},
|
||||||
{file = "rpds_py-0.10.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a65de5c02884760a14a58304fb6303f9ddfc582e630f385daea871e1bdb18686"},
|
{file = "rpds_py-0.10.3-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:763ad59e105fca09705d9f9b29ecffb95ecdc3b0363be3bb56081b2c6de7977a"},
|
||||||
{file = "rpds_py-0.10.2-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e92e5817eb6bfed23aa5e45bfe30647b83602bdd6f9e25d63524d4e6258458b0"},
|
{file = "rpds_py-0.10.3-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:187700668c018a7e76e89424b7c1042f317c8df9161f00c0c903c82b0a8cac5c"},
|
||||||
{file = "rpds_py-0.10.2-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:2c8fc6c841ada60a86d29c9ebe2e8757c47eda6553f3596c560e59ca6e9b6fa1"},
|
{file = "rpds_py-0.10.3-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:5267cfda873ad62591b9332fd9472d2409f7cf02a34a9c9cb367e2c0255994bf"},
|
||||||
{file = "rpds_py-0.10.2-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:8557c807388e6617161fe51b1a4747ea8d1133f2d2ad8e79583439abebe58fbd"},
|
{file = "rpds_py-0.10.3-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:2ed83d53a8c5902ec48b90b2ac045e28e1698c0bea9441af9409fc844dc79496"},
|
||||||
{file = "rpds_py-0.10.2-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:00e97d43a36811b78fa9ad9d3329bf34f76a31e891a7031a2ac01450c9b168ab"},
|
{file = "rpds_py-0.10.3-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:255f1a10ae39b52122cce26ce0781f7a616f502feecce9e616976f6a87992d6b"},
|
||||||
{file = "rpds_py-0.10.2-cp38-none-win32.whl", hash = "sha256:1ed3d5385d14be894e12a9033be989e012214a9811e7194849c94032ad69682a"},
|
{file = "rpds_py-0.10.3-cp38-none-win32.whl", hash = "sha256:a019a344312d0b1f429c00d49c3be62fa273d4a1094e1b224f403716b6d03be1"},
|
||||||
{file = "rpds_py-0.10.2-cp38-none-win_amd64.whl", hash = "sha256:02b4a2e28eb24dac4ef43dda4f6a6f7766e355179b143f7d0c76a1c5488a307b"},
|
{file = "rpds_py-0.10.3-cp38-none-win_amd64.whl", hash = "sha256:efb9ece97e696bb56e31166a9dd7919f8f0c6b31967b454718c6509f29ef6fee"},
|
||||||
{file = "rpds_py-0.10.2-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:2a55631b93e47956fbc97d69ba2054a8c6a4016f9a3064ec4e031f5f1030cb90"},
|
{file = "rpds_py-0.10.3-cp39-cp39-macosx_10_7_x86_64.whl", hash = "sha256:570cc326e78ff23dec7f41487aa9c3dffd02e5ee9ab43a8f6ccc3df8f9327623"},
|
||||||
{file = "rpds_py-0.10.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:2ffbf1b38c88d0466de542e91b08225d51782282512f8e2b11715126c41fda48"},
|
{file = "rpds_py-0.10.3-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cff7351c251c7546407827b6a37bcef6416304fc54d12d44dbfecbb717064717"},
|
||||||
{file = "rpds_py-0.10.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:213f9ef5c02ec2f883c1075d25a873149daadbaea50d18d622e9db55ec9849c2"},
|
{file = "rpds_py-0.10.3-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:177914f81f66c86c012311f8c7f46887ec375cfcfd2a2f28233a3053ac93a569"},
|
||||||
{file = "rpds_py-0.10.2-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b00150a9a3fd0a8efaa90bc2696c105b04039d50763dd1c95a34c88c5966cb57"},
|
{file = "rpds_py-0.10.3-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:448a66b8266de0b581246ca7cd6a73b8d98d15100fb7165974535fa3b577340e"},
|
||||||
{file = "rpds_py-0.10.2-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ab0f7aabdbce4a202e013083eeab71afdb85efa405dc4a06fea98cde81204675"},
|
{file = "rpds_py-0.10.3-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3bbac1953c17252f9cc675bb19372444aadf0179b5df575ac4b56faaec9f6294"},
|
||||||
{file = "rpds_py-0.10.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2cd0c9fb5d40887500b4ed818770c68ab4fa6e0395d286f9704be6751b1b7d98"},
|
{file = "rpds_py-0.10.3-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9dd9d9d9e898b9d30683bdd2b6c1849449158647d1049a125879cb397ee9cd12"},
|
||||||
{file = "rpds_py-0.10.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b8578fc6c8bdd0201327503720fa581000b4bd3934abbf07e2628d1ad3de157d"},
|
{file = "rpds_py-0.10.3-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e8c71ea77536149e36c4c784f6d420ffd20bea041e3ba21ed021cb40ce58e2c9"},
|
||||||
{file = "rpds_py-0.10.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d27d08056fcd61ff47a0cd8407eff4d3e816c82cb6b9c6f0ce9a0ad49225f81"},
|
{file = "rpds_py-0.10.3-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:16a472300bc6c83fe4c2072cc22b3972f90d718d56f241adabc7ae509f53f154"},
|
||||||
{file = "rpds_py-0.10.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:c8f6526df47953b07c45b95c4d1da6b9a0861c0e5da0271db96bb1d807825412"},
|
{file = "rpds_py-0.10.3-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b9255e7165083de7c1d605e818025e8860636348f34a79d84ec533546064f07e"},
|
||||||
{file = "rpds_py-0.10.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:177c033e467a66a054dd3a9534167234a3d0b2e41445807b13b626e01da25d92"},
|
{file = "rpds_py-0.10.3-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:53d7a3cd46cdc1689296348cb05ffd4f4280035770aee0c8ead3bbd4d6529acc"},
|
||||||
{file = "rpds_py-0.10.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:9c74cbee9e532dc34371127f7686d6953e5153a1f22beab7f953d95ee4a0fe09"},
|
{file = "rpds_py-0.10.3-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:22da15b902f9f8e267020d1c8bcfc4831ca646fecb60254f7bc71763569f56b1"},
|
||||||
{file = "rpds_py-0.10.2-cp39-none-win32.whl", hash = "sha256:05a1382905026bdd560f806c8c7c16e0f3e3fb359ba8868203ca6e5799884968"},
|
{file = "rpds_py-0.10.3-cp39-none-win32.whl", hash = "sha256:850c272e0e0d1a5c5d73b1b7871b0a7c2446b304cec55ccdb3eaac0d792bb065"},
|
||||||
{file = "rpds_py-0.10.2-cp39-none-win_amd64.whl", hash = "sha256:3fd503c27e7b7034128e30847ecdb4bff4ca5e60f29ad022a9f66ae8940d54ac"},
|
{file = "rpds_py-0.10.3-cp39-none-win_amd64.whl", hash = "sha256:de61e424062173b4f70eec07e12469edde7e17fa180019a2a0d75c13a5c5dc57"},
|
||||||
{file = "rpds_py-0.10.2-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:4a96147791e49e84207dd1530109aa0e9eeaf1c8b7a59f150047fc0fcdf9bb64"},
|
{file = "rpds_py-0.10.3-pp310-pypy310_pp73-macosx_10_7_x86_64.whl", hash = "sha256:af247fd4f12cca4129c1b82090244ea5a9d5bb089e9a82feb5a2f7c6a9fe181d"},
|
||||||
{file = "rpds_py-0.10.2-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:203eb1532d51591d32e8dfafd60b5d31347ea7278c8da02b4b550287f6abe28b"},
|
{file = "rpds_py-0.10.3-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:3ad59efe24a4d54c2742929001f2d02803aafc15d6d781c21379e3f7f66ec842"},
|
||||||
{file = "rpds_py-0.10.2-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a2f416cdfe92f5fbb77177f5f3f7830059d1582db05f2c7119bf80069d1ab69b"},
|
{file = "rpds_py-0.10.3-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:642ed0a209ced4be3a46f8cb094f2d76f1f479e2a1ceca6de6346a096cd3409d"},
|
||||||
{file = "rpds_py-0.10.2-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b2660000e1a113869c86eb5cc07f3343467490f3cd9d0299f81da9ddae7137b7"},
|
{file = "rpds_py-0.10.3-pp310-pypy310_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:37d0c59548ae56fae01c14998918d04ee0d5d3277363c10208eef8c4e2b68ed6"},
|
||||||
{file = "rpds_py-0.10.2-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1adb04e4b4e41bf30aaa77eeb169c1b9ba9e5010e2e6ce8d6c17e1446edc9b68"},
|
{file = "rpds_py-0.10.3-pp310-pypy310_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:aad6ed9e70ddfb34d849b761fb243be58c735be6a9265b9060d6ddb77751e3e8"},
|
||||||
{file = "rpds_py-0.10.2-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2bca97521ee786087f0c5ef318fef3eef0266a9c3deff88205523cf353af7394"},
|
{file = "rpds_py-0.10.3-pp310-pypy310_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8f94fdd756ba1f79f988855d948ae0bad9ddf44df296770d9a58c774cfbcca72"},
|
||||||
{file = "rpds_py-0.10.2-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4969592e3cdeefa4cbb15a26cec102cbd4a1d6e5b695fac9fa026e19741138c8"},
|
{file = "rpds_py-0.10.3-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:77076bdc8776a2b029e1e6ffbe6d7056e35f56f5e80d9dc0bad26ad4a024a762"},
|
||||||
{file = "rpds_py-0.10.2-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:df61f818edf7c8626bfa392f825860fb670b5f8336e238eb0ec7e2a5689cdded"},
|
{file = "rpds_py-0.10.3-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:87d9b206b1bd7a0523375dc2020a6ce88bca5330682ae2fe25e86fd5d45cea9c"},
|
||||||
{file = "rpds_py-0.10.2-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:b589d93a60e78fe55d5bc76ee8c2bf945dbdbb7cd16044c53e0307604e448de1"},
|
{file = "rpds_py-0.10.3-pp310-pypy310_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:8efaeb08ede95066da3a3e3c420fcc0a21693fcd0c4396d0585b019613d28515"},
|
||||||
{file = "rpds_py-0.10.2-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:73da69e1f612c3e682e34dcb971272d90d6f27b2c99acff444ca455a89978574"},
|
{file = "rpds_py-0.10.3-pp310-pypy310_pp73-musllinux_1_2_i686.whl", hash = "sha256:a4d9bfda3f84fc563868fe25ca160c8ff0e69bc4443c5647f960d59400ce6557"},
|
||||||
{file = "rpds_py-0.10.2-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:89438e8885a186c69fe31f7ef98bb2bf29688c466c3caf9060f404c0be89ae80"},
|
{file = "rpds_py-0.10.3-pp310-pypy310_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:d27aa6bbc1f33be920bb7adbb95581452cdf23005d5611b29a12bb6a3468cc95"},
|
||||||
{file = "rpds_py-0.10.2-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:c4ecc4e9a5d73a816cae36ee6b5d8b7a0c72013cae1e101406e832887c3dc2d8"},
|
{file = "rpds_py-0.10.3-pp38-pypy38_pp73-macosx_10_7_x86_64.whl", hash = "sha256:ed8313809571a5463fd7db43aaca68ecb43ca7a58f5b23b6e6c6c5d02bdc7882"},
|
||||||
{file = "rpds_py-0.10.2-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:907b214da5d2fcff0b6ddb83de1333890ca92abaf4bbf8d9c61dc1b95c87fd6e"},
|
{file = "rpds_py-0.10.3-pp38-pypy38_pp73-macosx_11_0_arm64.whl", hash = "sha256:e10e6a1ed2b8661201e79dff5531f8ad4cdd83548a0f81c95cf79b3184b20c33"},
|
||||||
{file = "rpds_py-0.10.2-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:bb44644371eaa29a3aba7b69b1862d0d56f073bb7585baa32e4271a71a91ee82"},
|
{file = "rpds_py-0.10.3-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:015de2ce2af1586ff5dc873e804434185199a15f7d96920ce67e50604592cae9"},
|
||||||
{file = "rpds_py-0.10.2-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:80c3cf46511653f94dfe07c7c79ab105c4164d6e1dfcb35b7214fb9af53eaef4"},
|
{file = "rpds_py-0.10.3-pp38-pypy38_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ae87137951bb3dc08c7d8bfb8988d8c119f3230731b08a71146e84aaa919a7a9"},
|
||||||
{file = "rpds_py-0.10.2-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaba0613c759ebf95988a84f766ca6b7432d55ce399194f95dde588ad1be0878"},
|
{file = "rpds_py-0.10.3-pp38-pypy38_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0bb4f48bd0dd18eebe826395e6a48b7331291078a879295bae4e5d053be50d4c"},
|
||||||
{file = "rpds_py-0.10.2-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0527c97dcd8bb983822ee31d3760187083fd3ba18ac4dd22cf5347c89d5628f4"},
|
{file = "rpds_py-0.10.3-pp38-pypy38_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:09362f86ec201288d5687d1dc476b07bf39c08478cde837cb710b302864e7ec9"},
|
||||||
{file = "rpds_py-0.10.2-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9cdfd649011ce2d90cb0dd304c5aba1190fac0c266d19a9e2b96b81cfd150a09"},
|
{file = "rpds_py-0.10.3-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:821392559d37759caa67d622d0d2994c7a3f2fb29274948ac799d496d92bca73"},
|
||||||
{file = "rpds_py-0.10.2-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:75eea40355a8690459c7291ce6c8ce39c27bd223675c7da6619f510c728feb97"},
|
{file = "rpds_py-0.10.3-pp38-pypy38_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7170cbde4070dc3c77dec82abf86f3b210633d4f89550fa0ad2d4b549a05572a"},
|
||||||
{file = "rpds_py-0.10.2-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:4f1b804cfad04f862d6a84af9d1ad941b06f671878f0f7ecad6c92007d423de6"},
|
{file = "rpds_py-0.10.3-pp38-pypy38_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:5de11c041486681ce854c814844f4ce3282b6ea1656faae19208ebe09d31c5b8"},
|
||||||
{file = "rpds_py-0.10.2-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:bf77f9017fcfa1232f98598a637406e6c33982ccba8a5922339575c3e2b90ea5"},
|
{file = "rpds_py-0.10.3-pp38-pypy38_pp73-musllinux_1_2_i686.whl", hash = "sha256:4ed172d0c79f156c1b954e99c03bc2e3033c17efce8dd1a7c781bc4d5793dfac"},
|
||||||
{file = "rpds_py-0.10.2-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:46c4c550bf59ce05d6bff2c98053822549aaf9fbaf81103edea325e03350bca1"},
|
{file = "rpds_py-0.10.3-pp38-pypy38_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:11fdd1192240dda8d6c5d18a06146e9045cb7e3ba7c06de6973000ff035df7c6"},
|
||||||
{file = "rpds_py-0.10.2-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:46af4a742b90c7460e94214f923452c2c1d050a9da1d2b8d4c70cbc045e692b7"},
|
{file = "rpds_py-0.10.3-pp39-pypy39_pp73-macosx_10_7_x86_64.whl", hash = "sha256:f602881d80ee4228a2355c68da6b296a296cd22bbb91e5418d54577bbf17fa7c"},
|
||||||
{file = "rpds_py-0.10.2-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:2a86d246a160d98d820ee7d02dc18c923c228de095be362e57b9fd8970b2c4a1"},
|
{file = "rpds_py-0.10.3-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:691d50c99a937709ac4c4cd570d959a006bd6a6d970a484c84cc99543d4a5bbb"},
|
||||||
{file = "rpds_py-0.10.2-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ae141c9017f8f473a6ee07a9425da021816a9f8c0683c2e5442f0ccf56b0fc62"},
|
{file = "rpds_py-0.10.3-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:24cd91a03543a0f8d09cb18d1cb27df80a84b5553d2bd94cba5979ef6af5c6e7"},
|
||||||
{file = "rpds_py-0.10.2-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e1147bc3d0dd1e549d991110d0a09557ec9f925dbc1ca62871fcdab2ec9d716b"},
|
{file = "rpds_py-0.10.3-pp39-pypy39_pp73-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:fc2200e79d75b5238c8d69f6a30f8284290c777039d331e7340b6c17cad24a5a"},
|
||||||
{file = "rpds_py-0.10.2-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:fce7a8ee8d0f682c953c0188735d823f0fcb62779bf92cd6ba473a8e730e26ad"},
|
{file = "rpds_py-0.10.3-pp39-pypy39_pp73-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ea65b59882d5fa8c74a23f8960db579e5e341534934f43f3b18ec1839b893e41"},
|
||||||
{file = "rpds_py-0.10.2-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4c7f9d70f99e1fbcbf57c75328b80e1c0a7f6cad43e75efa90a97221be5efe15"},
|
{file = "rpds_py-0.10.3-pp39-pypy39_pp73-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:829e91f3a8574888b73e7a3feb3b1af698e717513597e23136ff4eba0bc8387a"},
|
||||||
{file = "rpds_py-0.10.2-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0b309908b6ff5ffbf6394818cb73b5a2a74073acee2c57fe8719046389aeff0d"},
|
{file = "rpds_py-0.10.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:eab75a8569a095f2ad470b342f2751d9902f7944704f0571c8af46bede438475"},
|
||||||
{file = "rpds_py-0.10.2-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:3ff1f585a0fdc1415bd733b804f33d386064a308672249b14828130dd43e7c31"},
|
{file = "rpds_py-0.10.3-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:061c3ff1f51ecec256e916cf71cc01f9975af8fb3af9b94d3c0cc8702cfea637"},
|
||||||
{file = "rpds_py-0.10.2-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:0188b580c490bccb031e9b67e9e8c695a3c44ac5e06218b152361eca847317c3"},
|
{file = "rpds_py-0.10.3-pp39-pypy39_pp73-musllinux_1_2_aarch64.whl", hash = "sha256:39d05e65f23a0fe897b6ac395f2a8d48c56ac0f583f5d663e0afec1da89b95da"},
|
||||||
{file = "rpds_py-0.10.2-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:abe081453166e206e3a8c6d8ace57214c17b6d9477d7601ac14a365344dbc1f4"},
|
{file = "rpds_py-0.10.3-pp39-pypy39_pp73-musllinux_1_2_i686.whl", hash = "sha256:4eca20917a06d2fca7628ef3c8b94a8c358f6b43f1a621c9815243462dcccf97"},
|
||||||
{file = "rpds_py-0.10.2-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:9118de88c16947eaf5b92f749e65b0501ea69e7c2be7bd6aefc12551622360e1"},
|
{file = "rpds_py-0.10.3-pp39-pypy39_pp73-musllinux_1_2_x86_64.whl", hash = "sha256:e8d0f0eca087630d58b8c662085529781fd5dc80f0a54eda42d5c9029f812599"},
|
||||||
{file = "rpds_py-0.10.2.tar.gz", hash = "sha256:289073f68452b96e70990085324be7223944c7409973d13ddfe0eea1c1b5663b"},
|
{file = "rpds_py-0.10.3.tar.gz", hash = "sha256:fcc1ebb7561a3e24a6588f7c6ded15d80aec22c66a070c757559b57b17ffd1cb"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2004,19 +1990,19 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "setuptools"
|
name = "setuptools"
|
||||||
version = "68.1.2"
|
version = "68.2.2"
|
||||||
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
description = "Easily download, build, install, upgrade, and uninstall Python packages"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "setuptools-68.1.2-py3-none-any.whl", hash = "sha256:3d8083eed2d13afc9426f227b24fd1659489ec107c0e86cec2ffdde5c92e790b"},
|
{file = "setuptools-68.2.2-py3-none-any.whl", hash = "sha256:b454a35605876da60632df1a60f736524eb73cc47bbc9f3f1ef1b644de74fd2a"},
|
||||||
{file = "setuptools-68.1.2.tar.gz", hash = "sha256:3d4dfa6d95f1b101d695a6160a7626e15583af71a5f52176efa5d39a054d475d"},
|
{file = "setuptools-68.2.2.tar.gz", hash = "sha256:4ac1475276d2f1c48684874089fefcd83bd7162ddaafb81fac866ba0db282a87"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5,<=7.1.2)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (==0.8.3)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
|
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-hoverxref (<2)", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier"]
|
||||||
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
|
testing = ["build[virtualenv]", "filelock (>=3.4.0)", "flake8-2020", "ini2toml[lite] (>=0.9)", "jaraco.develop (>=7.21)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pip (>=19.1)", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy (>=0.9.1)", "pytest-perf", "pytest-ruff", "pytest-timeout", "pytest-xdist", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel"]
|
||||||
testing-integration = ["build[virtualenv]", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
|
testing-integration = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "jaraco.envs (>=2.2)", "jaraco.path (>=3.2.0)", "packaging (>=23.1)", "pytest", "pytest-enabler", "pytest-xdist", "tomli", "virtualenv (>=13.0.0)", "wheel"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "shexjsg"
|
name = "shexjsg"
|
||||||
|
@ -2092,52 +2078,52 @@ pandas = ["pandas (>=1.3.5)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "sqlalchemy"
|
name = "sqlalchemy"
|
||||||
version = "2.0.20"
|
version = "2.0.21"
|
||||||
description = "Database Abstraction Library"
|
description = "Database Abstraction Library"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:759b51346aa388c2e606ee206c0bc6f15a5299f6174d1e10cadbe4530d3c7a98"},
|
{file = "SQLAlchemy-2.0.21-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1e7dc99b23e33c71d720c4ae37ebb095bebebbd31a24b7d99dfc4753d2803ede"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:1506e988ebeaaf316f183da601f24eedd7452e163010ea63dbe52dc91c7fc70e"},
|
{file = "SQLAlchemy-2.0.21-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:7f0c4ee579acfe6c994637527c386d1c22eb60bc1c1d36d940d8477e482095d4"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5768c268df78bacbde166b48be788b83dddaa2a5974b8810af422ddfe68a9bc8"},
|
{file = "SQLAlchemy-2.0.21-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3f7d57a7e140efe69ce2d7b057c3f9a595f98d0bbdfc23fd055efdfbaa46e3a5"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a3f0dd6d15b6dc8b28a838a5c48ced7455c3e1fb47b89da9c79cc2090b072a50"},
|
{file = "SQLAlchemy-2.0.21-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7ca38746eac23dd7c20bec9278d2058c7ad662b2f1576e4c3dbfcd7c00cc48fa"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:243d0fb261f80a26774829bc2cee71df3222587ac789b7eaf6555c5b15651eed"},
|
{file = "SQLAlchemy-2.0.21-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:3cf229704074bce31f7f47d12883afee3b0a02bb233a0ba45ddbfe542939cca4"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6eb6d77c31e1bf4268b4d61b549c341cbff9842f8e115ba6904249c20cb78a61"},
|
{file = "SQLAlchemy-2.0.21-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:fb87f763b5d04a82ae84ccff25554ffd903baafba6698e18ebaf32561f2fe4aa"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-win32.whl", hash = "sha256:bcb04441f370cbe6e37c2b8d79e4af9e4789f626c595899d94abebe8b38f9a4d"},
|
{file = "SQLAlchemy-2.0.21-cp310-cp310-win32.whl", hash = "sha256:89e274604abb1a7fd5c14867a412c9d49c08ccf6ce3e1e04fffc068b5b6499d4"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp310-cp310-win_amd64.whl", hash = "sha256:d32b5ffef6c5bcb452723a496bad2d4c52b346240c59b3e6dba279f6dcc06c14"},
|
{file = "SQLAlchemy-2.0.21-cp310-cp310-win_amd64.whl", hash = "sha256:e36339a68126ffb708dc6d1948161cea2a9e85d7d7b0c54f6999853d70d44430"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:dd81466bdbc82b060c3c110b2937ab65ace41dfa7b18681fdfad2f37f27acdd7"},
|
{file = "SQLAlchemy-2.0.21-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:bf8eebccc66829010f06fbd2b80095d7872991bfe8415098b9fe47deaaa58063"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6fe7d61dc71119e21ddb0094ee994418c12f68c61b3d263ebaae50ea8399c4d4"},
|
{file = "SQLAlchemy-2.0.21-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:b977bfce15afa53d9cf6a632482d7968477625f030d86a109f7bdfe8ce3c064a"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e4e571af672e1bb710b3cc1a9794b55bce1eae5aed41a608c0401885e3491179"},
|
{file = "SQLAlchemy-2.0.21-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ff3dc2f60dbf82c9e599c2915db1526d65415be323464f84de8db3e361ba5b9"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3364b7066b3c7f4437dd345d47271f1251e0cfb0aba67e785343cdbdb0fff08c"},
|
{file = "SQLAlchemy-2.0.21-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:44ac5c89b6896f4740e7091f4a0ff2e62881da80c239dd9408f84f75a293dae9"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:1be86ccea0c965a1e8cd6ccf6884b924c319fcc85765f16c69f1ae7148eba64b"},
|
{file = "SQLAlchemy-2.0.21-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:87bf91ebf15258c4701d71dcdd9c4ba39521fb6a37379ea68088ce8cd869b446"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:1d35d49a972649b5080557c603110620a86aa11db350d7a7cb0f0a3f611948a0"},
|
{file = "SQLAlchemy-2.0.21-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b69f1f754d92eb1cc6b50938359dead36b96a1dcf11a8670bff65fd9b21a4b09"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-win32.whl", hash = "sha256:27d554ef5d12501898d88d255c54eef8414576f34672e02fe96d75908993cf53"},
|
{file = "SQLAlchemy-2.0.21-cp311-cp311-win32.whl", hash = "sha256:af520a730d523eab77d754f5cf44cc7dd7ad2d54907adeb3233177eeb22f271b"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp311-cp311-win_amd64.whl", hash = "sha256:411e7f140200c02c4b953b3dbd08351c9f9818d2bd591b56d0fa0716bd014f1e"},
|
{file = "SQLAlchemy-2.0.21-cp311-cp311-win_amd64.whl", hash = "sha256:141675dae56522126986fa4ca713739d00ed3a6f08f3c2eb92c39c6dfec463ce"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:3c6aceebbc47db04f2d779db03afeaa2c73ea3f8dcd3987eb9efdb987ffa09a3"},
|
{file = "SQLAlchemy-2.0.21-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:7614f1eab4336df7dd6bee05bc974f2b02c38d3d0c78060c5faa4cd1ca2af3b8"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d3f175410a6db0ad96b10bfbb0a5530ecd4fcf1e2b5d83d968dd64791f810ed"},
|
{file = "SQLAlchemy-2.0.21-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d59cb9e20d79686aa473e0302e4a82882d7118744d30bb1dfb62d3c47141b3ec"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ea8186be85da6587456c9ddc7bf480ebad1a0e6dcbad3967c4821233a4d4df57"},
|
{file = "SQLAlchemy-2.0.21-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a95aa0672e3065d43c8aa80080cdd5cc40fe92dc873749e6c1cf23914c4b83af"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:c3d99ba99007dab8233f635c32b5cd24fb1df8d64e17bc7df136cedbea427897"},
|
{file = "SQLAlchemy-2.0.21-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:8c323813963b2503e54d0944813cd479c10c636e3ee223bcbd7bd478bf53c178"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:76fdfc0f6f5341987474ff48e7a66c3cd2b8a71ddda01fa82fedb180b961630a"},
|
{file = "SQLAlchemy-2.0.21-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:419b1276b55925b5ac9b4c7044e999f1787c69761a3c9756dec6e5c225ceca01"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp37-cp37m-win32.whl", hash = "sha256:d3793dcf5bc4d74ae1e9db15121250c2da476e1af8e45a1d9a52b1513a393459"},
|
{file = "SQLAlchemy-2.0.21-cp37-cp37m-win32.whl", hash = "sha256:4615623a490e46be85fbaa6335f35cf80e61df0783240afe7d4f544778c315a9"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp37-cp37m-win_amd64.whl", hash = "sha256:79fde625a0a55220d3624e64101ed68a059c1c1f126c74f08a42097a72ff66a9"},
|
{file = "SQLAlchemy-2.0.21-cp37-cp37m-win_amd64.whl", hash = "sha256:cca720d05389ab1a5877ff05af96551e58ba65e8dc65582d849ac83ddde3e231"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:599ccd23a7146e126be1c7632d1d47847fa9f333104d03325c4e15440fc7d927"},
|
{file = "SQLAlchemy-2.0.21-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:b4eae01faee9f2b17f08885e3f047153ae0416648f8e8c8bd9bc677c5ce64be9"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:1a58052b5a93425f656675673ef1f7e005a3b72e3f2c91b8acca1b27ccadf5f4"},
|
{file = "SQLAlchemy-2.0.21-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:3eb7c03fe1cd3255811cd4e74db1ab8dca22074d50cd8937edf4ef62d758cdf4"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:79543f945be7a5ada9943d555cf9b1531cfea49241809dd1183701f94a748624"},
|
{file = "SQLAlchemy-2.0.21-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c2d494b6a2a2d05fb99f01b84cc9af9f5f93bf3e1e5dbdafe4bed0c2823584c1"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:63e73da7fb030ae0a46a9ffbeef7e892f5def4baf8064786d040d45c1d6d1dc5"},
|
{file = "SQLAlchemy-2.0.21-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b19ae41ef26c01a987e49e37c77b9ad060c59f94d3b3efdfdbf4f3daaca7b5fe"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:3ce5e81b800a8afc870bb8e0a275d81957e16f8c4b62415a7b386f29a0cb9763"},
|
{file = "SQLAlchemy-2.0.21-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:fc6b15465fabccc94bf7e38777d665b6a4f95efd1725049d6184b3a39fd54880"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:cb0d3e94c2a84215532d9bcf10229476ffd3b08f481c53754113b794afb62d14"},
|
{file = "SQLAlchemy-2.0.21-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:014794b60d2021cc8ae0f91d4d0331fe92691ae5467a00841f7130fe877b678e"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-win32.whl", hash = "sha256:8dd77fd6648b677d7742d2c3cc105a66e2681cc5e5fb247b88c7a7b78351cf74"},
|
{file = "SQLAlchemy-2.0.21-cp38-cp38-win32.whl", hash = "sha256:0268256a34806e5d1c8f7ee93277d7ea8cc8ae391f487213139018b6805aeaf6"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp38-cp38-win_amd64.whl", hash = "sha256:6f8a934f9dfdf762c844e5164046a9cea25fabbc9ec865c023fe7f300f11ca4a"},
|
{file = "SQLAlchemy-2.0.21-cp38-cp38-win_amd64.whl", hash = "sha256:73c079e21d10ff2be54a4699f55865d4b275fd6c8bd5d90c5b1ef78ae0197301"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:26a3399eaf65e9ab2690c07bd5cf898b639e76903e0abad096cd609233ce5208"},
|
{file = "SQLAlchemy-2.0.21-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:785e2f2c1cb50d0a44e2cdeea5fd36b5bf2d79c481c10f3a88a8be4cfa2c4615"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:4cde2e1096cbb3e62002efdb7050113aa5f01718035ba9f29f9d89c3758e7e4e"},
|
{file = "SQLAlchemy-2.0.21-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:c111cd40910ffcb615b33605fc8f8e22146aeb7933d06569ac90f219818345ef"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d1b09ba72e4e6d341bb5bdd3564f1cea6095d4c3632e45dc69375a1dbe4e26ec"},
|
{file = "SQLAlchemy-2.0.21-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:c9cba4e7369de663611ce7460a34be48e999e0bbb1feb9130070f0685e9a6b66"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1b74eeafaa11372627ce94e4dc88a6751b2b4d263015b3523e2b1e57291102f0"},
|
{file = "SQLAlchemy-2.0.21-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50a69067af86ec7f11a8e50ba85544657b1477aabf64fa447fd3736b5a0a4f67"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:77d37c1b4e64c926fa3de23e8244b964aab92963d0f74d98cbc0783a9e04f501"},
|
{file = "SQLAlchemy-2.0.21-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:ccb99c3138c9bde118b51a289d90096a3791658da9aea1754667302ed6564f6e"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:eefebcc5c555803065128401a1e224a64607259b5eb907021bf9b175f315d2a6"},
|
{file = "SQLAlchemy-2.0.21-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:513fd5b6513d37e985eb5b7ed89da5fd9e72354e3523980ef00d439bc549c9e9"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-win32.whl", hash = "sha256:3423dc2a3b94125094897118b52bdf4d37daf142cbcf26d48af284b763ab90e9"},
|
{file = "SQLAlchemy-2.0.21-cp39-cp39-win32.whl", hash = "sha256:f9fefd6298433b6e9188252f3bff53b9ff0443c8fde27298b8a2b19f6617eeb9"},
|
||||||
{file = "SQLAlchemy-2.0.20-cp39-cp39-win_amd64.whl", hash = "sha256:5ed61e3463021763b853628aef8bc5d469fe12d95f82c74ef605049d810f3267"},
|
{file = "SQLAlchemy-2.0.21-cp39-cp39-win_amd64.whl", hash = "sha256:2e617727fe4091cedb3e4409b39368f424934c7faa78171749f704b49b4bb4ce"},
|
||||||
{file = "SQLAlchemy-2.0.20-py3-none-any.whl", hash = "sha256:63a368231c53c93e2b67d0c5556a9836fdcd383f7e3026a39602aad775b14acf"},
|
{file = "SQLAlchemy-2.0.21-py3-none-any.whl", hash = "sha256:ea7da25ee458d8f404b93eb073116156fd7d8c2a776d8311534851f28277b4ce"},
|
||||||
{file = "SQLAlchemy-2.0.20.tar.gz", hash = "sha256:ca8a5ff2aa7f3ade6c498aaafce25b1eaeabe4e42b73e25519183e4566a16fc6"},
|
{file = "SQLAlchemy-2.0.21.tar.gz", hash = "sha256:05b971ab1ac2994a14c56b35eaaa91f86ba080e9ad481b20d99d77f381bb6258"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.dependencies]
|
[package.dependencies]
|
||||||
|
@ -2184,13 +2170,13 @@ doc = ["reno", "sphinx", "tornado (>=4.5)"]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "typing-extensions"
|
name = "typing-extensions"
|
||||||
version = "4.7.1"
|
version = "4.8.0"
|
||||||
description = "Backported and Experimental Type Hints for Python 3.7+"
|
description = "Backported and Experimental Type Hints for Python 3.8+"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "typing_extensions-4.7.1-py3-none-any.whl", hash = "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36"},
|
{file = "typing_extensions-4.8.0-py3-none-any.whl", hash = "sha256:8f92fc8806f9a6b641eaa5318da32b44d401efaac0f6678c9bc448ba3605faa0"},
|
||||||
{file = "typing_extensions-4.7.1.tar.gz", hash = "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2"},
|
{file = "typing_extensions-4.8.0.tar.gz", hash = "sha256:df8e4339e9cb77357558cbdbceca33c303714cf861d1eef15e1070055ae8b7ef"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
|
@ -2209,13 +2195,13 @@ dev = ["flake8", "flake8-annotations", "flake8-bandit", "flake8-bugbear", "flake
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "urllib3"
|
name = "urllib3"
|
||||||
version = "2.0.4"
|
version = "2.0.5"
|
||||||
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
description = "HTTP library with thread-safe connection pooling, file post, and more."
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.7"
|
python-versions = ">=3.7"
|
||||||
files = [
|
files = [
|
||||||
{file = "urllib3-2.0.4-py3-none-any.whl", hash = "sha256:de7df1803967d2c2a98e4b11bb7d6bd9210474c46e8a0401514e3a42a75ebde4"},
|
{file = "urllib3-2.0.5-py3-none-any.whl", hash = "sha256:ef16afa8ba34a1f989db38e1dbbe0c302e4289a47856990d0682e374563ce35e"},
|
||||||
{file = "urllib3-2.0.4.tar.gz", hash = "sha256:8d22f86aae8ef5e410d4f539fde9ce6b2113a001bb4d189e0aed70642d602b11"},
|
{file = "urllib3-2.0.5.tar.gz", hash = "sha256:13abf37382ea2ce6fb744d4dad67838eec857c9f4f57009891805e0b5e123594"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
|
@ -2381,24 +2367,24 @@ files = [
|
||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "zipp"
|
name = "zipp"
|
||||||
version = "3.16.2"
|
version = "3.17.0"
|
||||||
description = "Backport of pathlib-compatible object wrapper for zip files"
|
description = "Backport of pathlib-compatible object wrapper for zip files"
|
||||||
optional = false
|
optional = false
|
||||||
python-versions = ">=3.8"
|
python-versions = ">=3.8"
|
||||||
files = [
|
files = [
|
||||||
{file = "zipp-3.16.2-py3-none-any.whl", hash = "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0"},
|
{file = "zipp-3.17.0-py3-none-any.whl", hash = "sha256:0e923e726174922dce09c53c59ad483ff7bbb8e572e00c7f7c46b88556409f31"},
|
||||||
{file = "zipp-3.16.2.tar.gz", hash = "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147"},
|
{file = "zipp-3.17.0.tar.gz", hash = "sha256:84e64a1c28cf7e91ed2078bb8cc8c259cb19b76942096c8d7b84947690cabaf0"},
|
||||||
]
|
]
|
||||||
|
|
||||||
[package.extras]
|
[package.extras]
|
||||||
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"]
|
docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (<7.2.5)", "sphinx (>=3.5)", "sphinx-lint"]
|
||||||
testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"]
|
testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "pytest (>=6)", "pytest-black (>=0.3.7)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-ignore-flaky", "pytest-mypy (>=0.9.1)", "pytest-ruff"]
|
||||||
|
|
||||||
[extras]
|
[extras]
|
||||||
plot = ["dash", "dash-cytoscape"]
|
plot = ["dash", "dash-cytoscape"]
|
||||||
tests = ["coverage", "coveralls", "pytest", "pytest-cov", "pytest-depends", "pytest-emoji", "pytest-md", "pytest-profiling"]
|
tests = ["coverage", "coveralls", "pytest", "pytest-cov", "pytest-depends", "pytest-md", "pytest-profiling"]
|
||||||
|
|
||||||
[metadata]
|
[metadata]
|
||||||
lock-version = "2.0"
|
lock-version = "2.0"
|
||||||
python-versions = "^3.11"
|
python-versions = "^3.11"
|
||||||
content-hash = "9ef89b731746d07d428c6cff4a8c8b4771fbfcfcc8f17120ce3c6089e5161eb6"
|
content-hash = "7a4e1c3b66143e4f4e8392238051241f25274ebd597183ef64168055949074f4"
|
||||||
|
|
|
@ -65,11 +65,11 @@ build-backend = "poetry.core.masonry.api"
|
||||||
|
|
||||||
|
|
||||||
[tool.pytest.ini_options]
|
[tool.pytest.ini_options]
|
||||||
addopts = [
|
#addopts = [
|
||||||
"--cov=nwb_linkml",
|
# "--cov=nwb_linkml",
|
||||||
"--cov-append",
|
# "--cov-append",
|
||||||
"--cov-config=.coveragerc"
|
# "--cov-config=.coveragerc"
|
||||||
]
|
#]
|
||||||
testpaths = [
|
testpaths = [
|
||||||
"tests",
|
"tests",
|
||||||
'nwb_linkml/tests'
|
'nwb_linkml/tests'
|
||||||
|
|
|
@ -19,11 +19,12 @@ The `serialize` method
|
||||||
import pdb
|
import pdb
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from typing import List, Dict, Set, Tuple, Optional, TypedDict
|
from typing import List, Dict, Set, Tuple, Optional, TypedDict, Type
|
||||||
import os, sys
|
import os, sys
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
from copy import deepcopy, copy
|
from copy import deepcopy, copy
|
||||||
import warnings
|
import warnings
|
||||||
|
import inspect
|
||||||
|
|
||||||
from nwb_linkml.maps import flat_to_npytyping
|
from nwb_linkml.maps import flat_to_npytyping
|
||||||
from linkml.generators import PydanticGenerator
|
from linkml.generators import PydanticGenerator
|
||||||
|
@ -48,10 +49,14 @@ from linkml.utils.ifabsent_functions import ifabsent_value_declaration
|
||||||
from nwb_linkml.maps.naming import module_case, version_module_case
|
from nwb_linkml.maps.naming import module_case, version_module_case
|
||||||
|
|
||||||
from jinja2 import Template
|
from jinja2 import Template
|
||||||
|
from pydantic import BaseModel
|
||||||
|
|
||||||
|
class LinkML_Meta(BaseModel):
|
||||||
|
"""Extra LinkML Metadata stored as a class attribute"""
|
||||||
|
tree_root: bool = False
|
||||||
|
|
||||||
|
|
||||||
|
def default_template(pydantic_ver: str = "1", extra_classes:Optional[List[Type[BaseModel]]] = None) -> str:
|
||||||
def default_template(pydantic_ver: str = "1") -> str:
|
|
||||||
"""Constructs a default template for pydantic classes based on the version of pydantic"""
|
"""Constructs a default template for pydantic classes based on the version of pydantic"""
|
||||||
### HEADER ###
|
### HEADER ###
|
||||||
template = """
|
template = """
|
||||||
|
@ -94,7 +99,6 @@ class ConfiguredBaseModel(WeakRefShimBaseModel,
|
||||||
extra = {% if allow_extra %}'allow'{% else %}'forbid'{% endif %},
|
extra = {% if allow_extra %}'allow'{% else %}'forbid'{% endif %},
|
||||||
arbitrary_types_allowed = True,
|
arbitrary_types_allowed = True,
|
||||||
use_enum_values = True):
|
use_enum_values = True):
|
||||||
pass
|
|
||||||
"""
|
"""
|
||||||
else:
|
else:
|
||||||
template += """
|
template += """
|
||||||
|
@ -104,8 +108,22 @@ class ConfiguredBaseModel(BaseModel,
|
||||||
extra = {% if allow_extra %}'allow'{% else %}'forbid'{% endif %},
|
extra = {% if allow_extra %}'allow'{% else %}'forbid'{% endif %},
|
||||||
arbitrary_types_allowed = True,
|
arbitrary_types_allowed = True,
|
||||||
use_enum_values = True):
|
use_enum_values = True):
|
||||||
pass
|
|
||||||
"""
|
"""
|
||||||
|
### Injected Fields
|
||||||
|
template += """
|
||||||
|
{%- if injected_fields != None -%}
|
||||||
|
{% for field in injected_fields %}
|
||||||
|
{{ field }}
|
||||||
|
{% endfor %}
|
||||||
|
{%- else -%}
|
||||||
|
pass
|
||||||
|
{%- endif -%}
|
||||||
|
"""
|
||||||
|
### Extra classes
|
||||||
|
if extra_classes is not None:
|
||||||
|
template += """{{ '\n\n' }}"""
|
||||||
|
for cls in extra_classes:
|
||||||
|
template += inspect.getsource(cls) + '\n\n'
|
||||||
### ENUMS ###
|
### ENUMS ###
|
||||||
template += """
|
template += """
|
||||||
{% for e in enums.values() %}
|
{% for e in enums.values() %}
|
||||||
|
@ -142,11 +160,15 @@ class {{ c.name }}
|
||||||
\"\"\"
|
\"\"\"
|
||||||
{%- endif %}
|
{%- endif %}
|
||||||
{% for attr in c.attributes.values() if c.attributes -%}
|
{% for attr in c.attributes.values() if c.attributes -%}
|
||||||
{{attr.name}}: {%- if attr.equals_string -%}
|
{{attr.name}}:{{ ' ' }}{%- if attr.equals_string -%}
|
||||||
Literal[{{ predefined_slot_values[c.name][attr.name] }}]
|
Literal[{{ predefined_slot_values[c.name][attr.name] }}]
|
||||||
{%- else -%}
|
{%- else -%}
|
||||||
{{ attr.annotations['python_range'].value }}
|
{{ attr.annotations['python_range'].value }}
|
||||||
{%- endif -%} = Field(
|
{%- endif -%}
|
||||||
|
{%- if attr.annotations['fixed_field'] -%}
|
||||||
|
{{ ' ' }}= {{ attr.annotations['fixed_field'].value }}
|
||||||
|
{%- else -%}
|
||||||
|
{{ ' ' }}= Field(
|
||||||
{%- if predefined_slot_values[c.name][attr.name] -%}
|
{%- if predefined_slot_values[c.name][attr.name] -%}
|
||||||
{{ predefined_slot_values[c.name][attr.name] }}
|
{{ predefined_slot_values[c.name][attr.name] }}
|
||||||
{%- elif attr.required -%}
|
{%- elif attr.required -%}
|
||||||
|
@ -159,6 +181,7 @@ class {{ c.name }}
|
||||||
{%- if attr.minimum_value != None %}, ge={{attr.minimum_value}}{% endif -%}
|
{%- if attr.minimum_value != None %}, ge={{attr.minimum_value}}{% endif -%}
|
||||||
{%- if attr.maximum_value != None %}, le={{attr.maximum_value}}{% endif -%}
|
{%- if attr.maximum_value != None %}, le={{attr.maximum_value}}{% endif -%}
|
||||||
)
|
)
|
||||||
|
{%- endif %}
|
||||||
{% else -%}
|
{% else -%}
|
||||||
None
|
None
|
||||||
{% endfor %}
|
{% endfor %}
|
||||||
|
@ -192,6 +215,9 @@ class NWBPydanticGenerator(PydanticGenerator):
|
||||||
# SKIP_SLOTS=('VectorData',)
|
# SKIP_SLOTS=('VectorData',)
|
||||||
SKIP_SLOTS=('',)
|
SKIP_SLOTS=('',)
|
||||||
SKIP_CLASSES=('',)
|
SKIP_CLASSES=('',)
|
||||||
|
INJECTED_FIELDS = (
|
||||||
|
'hdf5_path: Optional[str] = Field(None, description="The absolute path that this object is stored in an NWB file")',
|
||||||
|
)
|
||||||
# SKIP_CLASSES=('VectorData','VectorIndex')
|
# SKIP_CLASSES=('VectorData','VectorIndex')
|
||||||
split:bool=True
|
split:bool=True
|
||||||
schema_map:Optional[Dict[str, SchemaDefinition]]=None
|
schema_map:Optional[Dict[str, SchemaDefinition]]=None
|
||||||
|
@ -410,6 +436,18 @@ class NWBPydanticGenerator(PydanticGenerator):
|
||||||
union += '\n' + ' '*4 + ']'
|
union += '\n' + ' '*4 + ']'
|
||||||
return union
|
return union
|
||||||
|
|
||||||
|
def _get_linkml_classvar(self, cls:ClassDefinition) -> SlotDefinition:
|
||||||
|
"""A class variable that holds additional linkml attrs"""
|
||||||
|
slot = SlotDefinition(
|
||||||
|
name='linkml_meta'
|
||||||
|
)
|
||||||
|
slot.annotations['python_range'] = Annotation('python_range', 'ClassVar[LinkML_Meta]')
|
||||||
|
meta_fields = {k: getattr(cls, k, None) for k in LinkML_Meta.model_fields.keys()}
|
||||||
|
meta_field_strings = [f'{k}={v}' for k,v in meta_fields.items() if v is not None]
|
||||||
|
meta_field_string = ', '.join(meta_field_strings)
|
||||||
|
slot.annotations['fixed_field'] = Annotation('fixed_field', f'Field(LinkML_Meta({meta_field_string}), frozen=True)')
|
||||||
|
|
||||||
|
return slot
|
||||||
|
|
||||||
def sort_classes(self, clist: List[ClassDefinition], imports:Dict[str, List[str]]) -> List[ClassDefinition]:
|
def sort_classes(self, clist: List[ClassDefinition], imports:Dict[str, List[str]]) -> List[ClassDefinition]:
|
||||||
"""
|
"""
|
||||||
|
@ -538,7 +576,8 @@ class NWBPydanticGenerator(PydanticGenerator):
|
||||||
with open(self.template_file) as template_file:
|
with open(self.template_file) as template_file:
|
||||||
template_obj = Template(template_file.read())
|
template_obj = Template(template_file.read())
|
||||||
else:
|
else:
|
||||||
template_obj = Template(default_template(self.pydantic_version))
|
template_obj = Template(default_template(self.pydantic_version,
|
||||||
|
extra_classes=[LinkML_Meta]))
|
||||||
|
|
||||||
sv: SchemaView
|
sv: SchemaView
|
||||||
sv = self.schemaview
|
sv = self.schemaview
|
||||||
|
@ -581,6 +620,9 @@ class NWBPydanticGenerator(PydanticGenerator):
|
||||||
for attribute in list(class_def.attributes.keys()):
|
for attribute in list(class_def.attributes.keys()):
|
||||||
del class_def.attributes[attribute]
|
del class_def.attributes[attribute]
|
||||||
|
|
||||||
|
# make class attr that stores extra linkml attrs
|
||||||
|
class_def.attributes['linkml_meta'] = self._get_linkml_classvar(class_def)
|
||||||
|
|
||||||
class_name = class_original.name
|
class_name = class_original.name
|
||||||
predefined_slot_values[camelcase(class_name)] = {}
|
predefined_slot_values[camelcase(class_name)] = {}
|
||||||
for s in class_slots[class_name]:
|
for s in class_slots[class_name]:
|
||||||
|
@ -632,6 +674,7 @@ class NWBPydanticGenerator(PydanticGenerator):
|
||||||
pyrange = f"Optional[{pyrange}]"
|
pyrange = f"Optional[{pyrange}]"
|
||||||
ann = Annotation("python_range", pyrange)
|
ann = Annotation("python_range", pyrange)
|
||||||
s.annotations[ann.tag] = ann
|
s.annotations[ann.tag] = ann
|
||||||
|
|
||||||
code = template_obj.render(
|
code = template_obj.render(
|
||||||
imports=imports,
|
imports=imports,
|
||||||
schema=pyschema,
|
schema=pyschema,
|
||||||
|
@ -642,6 +685,7 @@ class NWBPydanticGenerator(PydanticGenerator):
|
||||||
metamodel_version=self.schema.metamodel_version,
|
metamodel_version=self.schema.metamodel_version,
|
||||||
version=self.schema.version,
|
version=self.schema.version,
|
||||||
class_isa_plus_mixins=self.get_class_isa_plus_mixins(sorted_classes),
|
class_isa_plus_mixins=self.get_class_isa_plus_mixins(sorted_classes),
|
||||||
|
injected_fields=self.INJECTED_FIELDS
|
||||||
)
|
)
|
||||||
return code
|
return code
|
||||||
|
|
||||||
|
@ -678,3 +722,4 @@ def compile_python(text_or_fn: str, package_path: Path = None) -> ModuleType: #
|
||||||
|
|
||||||
exec(spec, module.__dict__)
|
exec(spec, module.__dict__)
|
||||||
return module
|
return module
|
||||||
|
|
||||||
|
|
|
@ -1,154 +1,79 @@
|
||||||
"""
|
"""
|
||||||
This is a sandbox file that should be split out to its own pydantic-hdf5 package, but just experimenting here to get our bearings
|
This is a sandbox file that should be split out to its own pydantic-hdf5 package, but just experimenting here to get our bearings
|
||||||
|
|
||||||
|
Notes:
|
||||||
|
|
||||||
|
* Rather than a set of recursive build steps as is used elsewhere in the package,
|
||||||
|
since we need to instantiate some models first that are referred to elsewhere, we
|
||||||
|
flatten the hdf5 file and build each from a queue.
|
||||||
|
|
||||||
|
Mapping operations (mostly TODO atm)
|
||||||
|
|
||||||
|
* Create new models from DynamicTables
|
||||||
|
* Handle softlinks as object references and vice versa by adding a ``path`` attr
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
Other TODO:
|
||||||
|
|
||||||
|
* Read metadata only, don't read all arrays
|
||||||
|
* Write, obvi lol.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
import pdb
|
import pdb
|
||||||
import typing
|
import typing
|
||||||
|
import warnings
|
||||||
from typing import Optional, List, Dict, overload, Literal, Type, Any
|
from typing import Optional, List, Dict, overload, Literal, Type, Any
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
from types import ModuleType
|
from types import ModuleType
|
||||||
from typing import TypeVar, TYPE_CHECKING
|
from typing import TypeVar, TYPE_CHECKING, NamedTuple
|
||||||
from abc import abstractmethod
|
from abc import abstractmethod
|
||||||
import json
|
import json
|
||||||
|
import subprocess
|
||||||
|
import shutil
|
||||||
|
|
||||||
import h5py
|
import h5py
|
||||||
from pydantic import BaseModel
|
from pydantic import BaseModel, Field, ConfigDict
|
||||||
from dataclasses import dataclass, field
|
from dataclasses import dataclass, field
|
||||||
|
|
||||||
from nwb_linkml.translate import generate_from_nwbfile
|
from nwb_linkml.translate import generate_from_nwbfile
|
||||||
#from nwb_linkml.models.core_nwb_file import NWBFile
|
#from nwb_linkml.models.core_nwb_file import NWBFile
|
||||||
if TYPE_CHECKING:
|
if TYPE_CHECKING:
|
||||||
from nwb_linkml.models.core_nwb_file import NWBFile
|
from nwb_linkml.models import NWBFile
|
||||||
from nwb_linkml.providers.schema import SchemaProvider
|
from nwb_linkml.providers.schema import SchemaProvider
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class HDF5Element():
|
|
||||||
|
|
||||||
cls: h5py.Dataset | h5py.Group
|
|
||||||
parent: Type[BaseModel]
|
|
||||||
model: Optional[Any] = None
|
|
||||||
root_model: Optional[Type[BaseModel]] = None
|
|
||||||
|
|
||||||
@abstractmethod
|
class H5SourceItem(BaseModel):
|
||||||
def read(self) -> BaseModel | List[BaseModel]:
|
"""Tuple of items for each element when flattening an hdf5 file"""
|
||||||
"""
|
path: str
|
||||||
Constructs the pydantic model from the given hdf5 element
|
"""Absolute hdf5 path of element"""
|
||||||
"""
|
leaf: bool
|
||||||
|
"""If ``True``, this item has no children (and thus we should start instantiating it before ascending to parent classes)"""
|
||||||
|
h5_type: Literal['group', 'dataset']
|
||||||
|
"""What kind of hdf5 element this is"""
|
||||||
|
depends: List[str] = Field(default_factory=list)
|
||||||
|
"""Paths of other source items that this item depends on before it can be instantiated. eg. from softlinks"""
|
||||||
|
|
||||||
@abstractmethod
|
|
||||||
def write(self) -> h5py.Dataset | h5py.Group:
|
|
||||||
"""
|
|
||||||
Create the h5py object from the in-memory pydantic model
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
model_config = ConfigDict(arbitrary_types_allowed=True)
|
||||||
@property
|
@property
|
||||||
def name(self) -> str:
|
def parts(self) -> List[str]:
|
||||||
"""Just the terminal group name"""
|
"""path split by /"""
|
||||||
return self.cls.name.split('/')[-1]
|
return self.path.split('/')
|
||||||
|
|
||||||
def get_model(self) -> Type[BaseModel | dict | list]:
|
|
||||||
"""
|
|
||||||
Find our model
|
|
||||||
- If we have a neurodata_type in our attrs, use that
|
|
||||||
- Otherwise, use our parent to resolve the type
|
|
||||||
"""
|
|
||||||
if self.model is not None:
|
|
||||||
return self.model
|
|
||||||
|
|
||||||
if 'neurodata_type' in self.cls.attrs.keys():
|
|
||||||
return get_model(self.cls)
|
|
||||||
else:
|
|
||||||
parent_model = get_model(self.cls.parent)
|
|
||||||
field = parent_model.model_fields.get(self.name)
|
|
||||||
if issubclass(type(field.annotation), BaseModel):
|
|
||||||
return field.annotation
|
|
||||||
else:
|
|
||||||
try:
|
|
||||||
if issubclass(field.annotation, BaseModel):
|
|
||||||
return field.annotation
|
|
||||||
except TypeError:
|
|
||||||
pass
|
|
||||||
# remove any optionals
|
|
||||||
annotation = field.annotation
|
|
||||||
annotation = unwrap_optional(annotation)
|
|
||||||
|
|
||||||
if typing.get_origin(annotation) is list:
|
|
||||||
return list
|
|
||||||
|
|
||||||
else:
|
|
||||||
return dict
|
|
||||||
#raise NotImplementedError('Need to unpack at least listlike annotations')
|
|
||||||
|
|
||||||
def unwrap_optional(annotation):
|
|
||||||
if typing.get_origin(annotation) == typing.Union:
|
|
||||||
args = typing.get_args(annotation)
|
|
||||||
|
|
||||||
if len(args) == 2 and args[1].__name__ == 'NoneType':
|
|
||||||
annotation = args[0]
|
|
||||||
return annotation
|
|
||||||
|
|
||||||
def take_outer_type(annotation):
|
|
||||||
if typing.get_origin(annotation) is list:
|
|
||||||
return list
|
|
||||||
return annotation
|
|
||||||
|
|
||||||
def submodel_by_path(model: BaseModel, path:str) -> Type[BaseModel | dict | list]:
|
|
||||||
"""
|
|
||||||
Given a pydantic model and an absolute HDF5 path, get the type annotation
|
|
||||||
"""
|
|
||||||
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class H5Dataset(HDF5Element):
|
|
||||||
cls: h5py.Dataset
|
|
||||||
|
|
||||||
def read(self) -> Any:
|
|
||||||
model = self.get_model()
|
|
||||||
|
|
||||||
# TODO: Handle references
|
|
||||||
if self.cls.dtype == h5py.ref_dtype:
|
|
||||||
return None
|
|
||||||
|
|
||||||
if self.cls.shape == ():
|
|
||||||
return self.cls[()]
|
|
||||||
elif model is list:
|
|
||||||
return self.cls[:].tolist()
|
|
||||||
else:
|
|
||||||
return {'array':self.cls[:], 'name': self.cls.name.split('/')[-1]}
|
|
||||||
#raise NotImplementedError('oop')
|
|
||||||
|
|
||||||
@dataclass
|
|
||||||
class H5Group(HDF5Element):
|
|
||||||
cls: h5py.Group
|
|
||||||
|
|
||||||
def read(self) -> BaseModel:
|
|
||||||
data = {}
|
|
||||||
model = self.get_model()
|
|
||||||
|
|
||||||
model_attrs = {
|
|
||||||
k:v for k, v in self.cls.attrs.items() if k in model.model_fields.keys()
|
|
||||||
}
|
|
||||||
data.update(model_attrs)
|
|
||||||
|
|
||||||
|
|
||||||
for k, v in self.cls.items():
|
|
||||||
child_model = None
|
|
||||||
if isinstance(model, type) and issubclass(model, BaseModel):
|
|
||||||
child_field = model.model_fields.get(k, None)
|
|
||||||
if child_field is not None:
|
|
||||||
child_model = unwrap_optional(child_field.annotation)
|
|
||||||
child_model = take_outer_type(child_model)
|
|
||||||
if isinstance(v, h5py.Group):
|
|
||||||
data[k] = H5Group(cls=v, parent=model, model=child_model).read()
|
|
||||||
elif isinstance(v, h5py.Dataset):
|
|
||||||
data[k] = H5Dataset(cls=v, parent=model, model=child_model).read()
|
|
||||||
|
|
||||||
|
|
||||||
if issubclass(model, BaseModel):
|
|
||||||
data['name'] = self.cls.name.split('/')[-1]
|
|
||||||
return model(**data)
|
|
||||||
elif model is list:
|
|
||||||
return list(data.values())
|
|
||||||
|
|
||||||
|
class ReadQueue(BaseModel):
|
||||||
|
"""Container model to store items as they are built """
|
||||||
|
queue: Dict[str,H5SourceItem] = Field(
|
||||||
|
default_factory=dict,
|
||||||
|
description="Items left to be instantiated, keyed by hdf5 path",
|
||||||
|
)
|
||||||
|
completed: Dict[str, BaseModel] = Field(
|
||||||
|
default_factory=dict,
|
||||||
|
description="Items that have already been instantiated, keyed by hdf5 path"
|
||||||
|
)
|
||||||
|
|
||||||
class HDF5IO():
|
class HDF5IO():
|
||||||
|
|
||||||
|
@ -169,19 +94,23 @@ class HDF5IO():
|
||||||
def read(self, path:str) -> BaseModel | Dict[str, BaseModel]: ...
|
def read(self, path:str) -> BaseModel | Dict[str, BaseModel]: ...
|
||||||
|
|
||||||
def read(self, path:Optional[str] = None):
|
def read(self, path:Optional[str] = None):
|
||||||
|
provider = self.make_provider()
|
||||||
|
|
||||||
h5f = h5py.File(str(self.path))
|
h5f = h5py.File(str(self.path))
|
||||||
schema = read_specs(h5f.get('specifications'))
|
|
||||||
# build schema so we have them cached
|
|
||||||
|
|
||||||
provider = SchemaProvider()
|
|
||||||
res = provider.build_from_dicts(schema)
|
|
||||||
|
|
||||||
if path:
|
if path:
|
||||||
src = h5f.get(path)
|
src = h5f.get(path)
|
||||||
parent = get_model(src)
|
|
||||||
else:
|
else:
|
||||||
src = h5f
|
src = h5f
|
||||||
parent = provider.get_class('core', 'NWBFile')
|
|
||||||
|
# get all children of selected item
|
||||||
|
if isinstance(src, (h5py.File, h5py.Group)):
|
||||||
|
children = self._flatten_hdf(src)
|
||||||
|
else:
|
||||||
|
raise NotImplementedError('directly read individual datasets')
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
data = {}
|
data = {}
|
||||||
for k, v in src.items():
|
for k, v in src.items():
|
||||||
|
@ -199,6 +128,38 @@ class HDF5IO():
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def make_provider(self) -> SchemaProvider:
|
||||||
|
"""
|
||||||
|
Create a :class:`~.providers.schema.SchemaProvider` by
|
||||||
|
reading specifications from the NWBFile ``/specification`` group and translating
|
||||||
|
them to LinkML and generating pydantic models
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
:class:`~.providers.schema.SchemaProvider` : Schema Provider with correct versions
|
||||||
|
specified as defaults
|
||||||
|
"""
|
||||||
|
h5f = h5py.File(str(self.path))
|
||||||
|
schema = read_specs_as_dicts(h5f.get('specifications'))
|
||||||
|
|
||||||
|
# get versions for each namespace
|
||||||
|
versions = {}
|
||||||
|
for ns_schema in schema.values():
|
||||||
|
# each "namespace" can actually contain multiple namespaces which actually contain the version info
|
||||||
|
for inner_ns in ns_schema['namespace']['namespaces']:
|
||||||
|
versions[inner_ns['name']] = inner_ns['version']
|
||||||
|
|
||||||
|
provider = SchemaProvider(versions=versions)
|
||||||
|
|
||||||
|
# build schema so we have them cached
|
||||||
|
provider.build_from_dicts(schema)
|
||||||
|
h5f.close()
|
||||||
|
return provider
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def process_group(self, group:h5py.Group|h5py.File) -> dict | list:
|
def process_group(self, group:h5py.Group|h5py.File) -> dict | list:
|
||||||
attrs = dict(group.attrs)
|
attrs = dict(group.attrs)
|
||||||
|
|
||||||
|
@ -233,7 +194,17 @@ class HDF5IO():
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
def read_specs(group: h5py.Group) -> dict:
|
def read_specs_as_dicts(group: h5py.Group) -> dict:
|
||||||
|
"""
|
||||||
|
Utility function to iterate through the `/specifications` group and
|
||||||
|
load
|
||||||
|
|
||||||
|
Args:
|
||||||
|
group:
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
|
||||||
|
"""
|
||||||
spec_dict = {}
|
spec_dict = {}
|
||||||
def _read_spec(name, node):
|
def _read_spec(name, node):
|
||||||
|
|
||||||
|
@ -263,4 +234,136 @@ def get_model(cls: h5py.Group | h5py.Dataset) -> Type[BaseModel]:
|
||||||
return mod.model_fields[cls.name.split('/')[-1]].annotation
|
return mod.model_fields[cls.name.split('/')[-1]].annotation
|
||||||
|
|
||||||
|
|
||||||
|
def truncate_file(source: Path, target: Optional[Path] = None, n:int=10) -> Path:
|
||||||
|
"""
|
||||||
|
Create a truncated HDF5 file where only the first few samples are kept.
|
||||||
|
|
||||||
|
Used primarily to create testing data from real data without it being so damn bit
|
||||||
|
|
||||||
|
Args:
|
||||||
|
source (:class:`pathlib.Path`): Source hdf5 file
|
||||||
|
target (:class:`pathlib.Path`): Optional - target hdf5 file to write to. If ``None``, use ``{source}_truncated.hdf5``
|
||||||
|
n (int): The number of items from datasets (samples along the 0th dimension of a dataset) to include
|
||||||
|
|
||||||
|
Returns:
|
||||||
|
:class:`pathlib.Path` path of the truncated file
|
||||||
|
"""
|
||||||
|
if target is None:
|
||||||
|
target = source.parent / (source.stem + '_truncated.hdf5')
|
||||||
|
else:
|
||||||
|
target = Path(target)
|
||||||
|
|
||||||
|
source = Path(source)
|
||||||
|
|
||||||
|
# and also a temporary file that we'll make with h5repack
|
||||||
|
target_tmp = target.parent / (target.stem + '_tmp.hdf5')
|
||||||
|
|
||||||
|
|
||||||
|
# copy the whole thing
|
||||||
|
if target.exists():
|
||||||
|
target.unlink()
|
||||||
|
shutil.copy(source, target)
|
||||||
|
|
||||||
|
h5f_target = h5py.File(str(target), 'r+')
|
||||||
|
def _prune_dataset(name:str, obj: h5py.Dataset | h5py.Group):
|
||||||
|
|
||||||
|
if isinstance(obj, h5py.Dataset):
|
||||||
|
if obj.size > 10:
|
||||||
|
try:
|
||||||
|
obj.resize(n, axis=0)
|
||||||
|
except TypeError:
|
||||||
|
# contiguous arrays cant be resized directly
|
||||||
|
# so we have to jank our way through it
|
||||||
|
tmp_name = obj.name + '__tmp'
|
||||||
|
original_name = obj.name
|
||||||
|
obj.parent.move(obj.name, tmp_name)
|
||||||
|
old_obj = obj.parent.get(tmp_name)
|
||||||
|
new_obj = obj.parent.create_dataset(original_name, data=old_obj[0:n])
|
||||||
|
for k, v in old_obj.attrs.items():
|
||||||
|
new_obj.attrs[k] = v
|
||||||
|
del new_obj.parent[tmp_name]
|
||||||
|
|
||||||
|
|
||||||
|
h5f_target.visititems(_prune_dataset)
|
||||||
|
h5f_target.flush()
|
||||||
|
h5f_target.close()
|
||||||
|
|
||||||
|
# use h5repack to actually remove the items from the dataset
|
||||||
|
if shutil.which('h5repack') is None:
|
||||||
|
warnings.warn('Truncated file made, but since h5repack not found in path, file wont be any smaller')
|
||||||
|
return target
|
||||||
|
|
||||||
|
res = subprocess.run(
|
||||||
|
['h5repack', '-f', 'GZIP=9', str(target), str(target_tmp)],
|
||||||
|
capture_output=True
|
||||||
|
)
|
||||||
|
if res.returncode != 0:
|
||||||
|
warnings.warn(f'h5repack did not return 0: {res.stderr} {res.stdout}')
|
||||||
|
# remove the attempt at the repack
|
||||||
|
target_tmp.unlink()
|
||||||
|
return target
|
||||||
|
|
||||||
|
target.unlink()
|
||||||
|
target_tmp.rename(target)
|
||||||
|
|
||||||
|
return target
|
||||||
|
|
||||||
|
def unwrap_optional(annotation):
|
||||||
|
if typing.get_origin(annotation) == typing.Union:
|
||||||
|
args = typing.get_args(annotation)
|
||||||
|
|
||||||
|
if len(args) == 2 and args[1].__name__ == 'NoneType':
|
||||||
|
annotation = args[0]
|
||||||
|
return annotation
|
||||||
|
|
||||||
|
def take_outer_type(annotation):
|
||||||
|
if typing.get_origin(annotation) is list:
|
||||||
|
return list
|
||||||
|
return annotation
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
|
def submodel_by_path(model: BaseModel, path:str) -> Type[BaseModel | dict | list]:
|
||||||
|
"""
|
||||||
|
Given a pydantic model and an absolute HDF5 path, get the type annotation
|
||||||
|
"""
|
||||||
|
parts = path.split('/')
|
||||||
|
for part in parts:
|
||||||
|
ann = model.model_fields[part].annotation
|
||||||
|
|
||||||
|
|
||||||
|
def flatten_hdf(h5f:h5py.File | h5py.Group, skip='specifications') -> Dict[str, H5SourceItem]:
|
||||||
|
"""
|
||||||
|
Flatten all child elements of hdf element into a dict of :class:`.H5SourceItem` s keyed by their path
|
||||||
|
|
||||||
|
Args:
|
||||||
|
h5f (:class:`h5py.File` | :class:`h5py.Group`): HDF file or group to flatten!
|
||||||
|
"""
|
||||||
|
items = {}
|
||||||
|
def _itemize(name: str, obj: h5py.Dataset | h5py.Group):
|
||||||
|
if skip in name:
|
||||||
|
return
|
||||||
|
leaf = isinstance(obj, h5py.Dataset) or len(obj.keys()) == 0
|
||||||
|
# get references in attrs and datasets
|
||||||
|
refs = [ref for ref in obj.attrs.values() if isinstance(ref, h5py.h5r.Reference)]
|
||||||
|
if isinstance(obj, h5py.Dataset):
|
||||||
|
h5_type = 'dataset'
|
||||||
|
if obj.shape == ():
|
||||||
|
if isinstance(obj[()], h5py.h5r.Reference):
|
||||||
|
refs.append(obj[()])
|
||||||
|
elif isinstance(obj[0], h5py.h5r.Reference):
|
||||||
|
refs.extend(obj[:].tolist())
|
||||||
|
else:
|
||||||
|
h5_type = 'group'
|
||||||
|
# dereference and get name of reference
|
||||||
|
depends = list(set([h5f[i].name for i in refs]))
|
||||||
|
items[name] = H5SourceItem.model_construct(
|
||||||
|
path = name,
|
||||||
|
leaf = leaf,
|
||||||
|
depends = depends
|
||||||
|
)
|
||||||
|
|
||||||
|
h5f.visititems(_itemize)
|
||||||
|
return items
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -172,7 +172,7 @@ class Provider(ABC):
|
||||||
return version_path
|
return version_path
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def versions(self) -> Dict[str,List[str]]:
|
def available_versions(self) -> Dict[str,List[str]]:
|
||||||
"""
|
"""
|
||||||
Dictionary mapping a namespace to a list of built versions
|
Dictionary mapping a namespace to a list of built versions
|
||||||
"""
|
"""
|
||||||
|
@ -511,7 +511,7 @@ class PydanticProvider(Provider):
|
||||||
path = LinkMLProvider(path=self.config.cache_dir).namespace_path(namespace, version) / 'namespace.yaml'
|
path = LinkMLProvider(path=self.config.cache_dir).namespace_path(namespace, version) / 'namespace.yaml'
|
||||||
if version is None:
|
if version is None:
|
||||||
# Get the most recently built version
|
# Get the most recently built version
|
||||||
version = LinkMLProvider(path=self.config.cache_dir).versions[name][-1]
|
version = LinkMLProvider(path=self.config.cache_dir).available_versions[name][-1]
|
||||||
fn = path.parts[-1]
|
fn = path.parts[-1]
|
||||||
else:
|
else:
|
||||||
# given a path to a namespace linkml yaml file
|
# given a path to a namespace linkml yaml file
|
||||||
|
@ -563,10 +563,8 @@ class PydanticProvider(Provider):
|
||||||
return serialized
|
return serialized
|
||||||
|
|
||||||
@classmethod
|
@classmethod
|
||||||
def module_name(self, namespace:str, version: Optional[str]=None) -> str:
|
def module_name(self, namespace:str, version: str) -> str:
|
||||||
name_pieces = ['nwb_linkml', 'models', 'pydantic', namespace]
|
name_pieces = ['nwb_linkml', 'models', 'pydantic', namespace, version_module_case(version), 'namespace']
|
||||||
if version is not None:
|
|
||||||
name_pieces.append(version_module_case(version))
|
|
||||||
module_name = '.'.join(name_pieces)
|
module_name = '.'.join(name_pieces)
|
||||||
return module_name
|
return module_name
|
||||||
def import_module(
|
def import_module(
|
||||||
|
@ -590,7 +588,7 @@ class PydanticProvider(Provider):
|
||||||
"""
|
"""
|
||||||
# get latest version if None
|
# get latest version if None
|
||||||
if version is None:
|
if version is None:
|
||||||
version = self.versions[namespace][-1]
|
version = self.available_versions[namespace][-1]
|
||||||
|
|
||||||
path = self.namespace_path(namespace, version) / 'namespace.py'
|
path = self.namespace_path(namespace, version) / 'namespace.py'
|
||||||
if not path.exists():
|
if not path.exists():
|
||||||
|
@ -602,7 +600,9 @@ class PydanticProvider(Provider):
|
||||||
spec.loader.exec_module(module)
|
spec.loader.exec_module(module)
|
||||||
return module
|
return module
|
||||||
|
|
||||||
def get(self, namespace: str, version: Optional[str] = None) -> ModuleType:
|
def get(self, namespace: str,
|
||||||
|
version: Optional[str] = None,
|
||||||
|
allow_repo: bool = True) -> ModuleType:
|
||||||
"""
|
"""
|
||||||
Get the imported module for a given namespace and version.
|
Get the imported module for a given namespace and version.
|
||||||
|
|
||||||
|
@ -628,22 +628,27 @@ class PydanticProvider(Provider):
|
||||||
namespace (str): Name of namespace to import. Must have either been previously built with :meth:`.PydanticProvider.build` or
|
namespace (str): Name of namespace to import. Must have either been previously built with :meth:`.PydanticProvider.build` or
|
||||||
a matching namespace/version combo must be available to the :class:`.LinkMLProvider`
|
a matching namespace/version combo must be available to the :class:`.LinkMLProvider`
|
||||||
version (Optional[str]): Version to import. If ``None``, get the most recently build module
|
version (Optional[str]): Version to import. If ``None``, get the most recently build module
|
||||||
|
allow_repo (bool): Allow getting modules provided within :mod:`nwb_linkml.models.pydantic`
|
||||||
|
|
||||||
Returns:
|
Returns:
|
||||||
The imported :class:`types.ModuleType` object that has all the built classes at the root level.
|
The imported :class:`types.ModuleType` object that has all the built classes at the root level.
|
||||||
|
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
if version is None:
|
||||||
|
version = self.available_versions[namespace][-1]
|
||||||
|
|
||||||
module_name = self.module_name(namespace, version)
|
module_name = self.module_name(namespace, version)
|
||||||
if module_name in sys.modules:
|
if module_name in sys.modules:
|
||||||
return sys.modules[module_name]
|
return sys.modules[module_name]
|
||||||
|
|
||||||
try:
|
try:
|
||||||
path = self.namespace_path(namespace, version)
|
path = self.namespace_path(namespace, version, allow_repo)
|
||||||
except FileNotFoundError:
|
except FileNotFoundError:
|
||||||
path = None
|
path = None
|
||||||
|
|
||||||
if path is None or not path.exists():
|
if path is None or not path.exists():
|
||||||
_ = self.build(namespace, version)
|
_ = self.build(namespace, version=version)
|
||||||
module = self.import_module(namespace, version)
|
module = self.import_module(namespace, version)
|
||||||
return module
|
return module
|
||||||
|
|
||||||
|
@ -689,6 +694,21 @@ class SchemaProvider(Provider):
|
||||||
Alias for :meth:`.LinkMLProvider.build_from_dicts` that also builds a pydantic model
|
Alias for :meth:`.LinkMLProvider.build_from_dicts` that also builds a pydantic model
|
||||||
"""
|
"""
|
||||||
|
|
||||||
|
def __init__(
|
||||||
|
self,
|
||||||
|
versions: Optional[Dict[str, str]] = None,
|
||||||
|
**kwargs
|
||||||
|
):
|
||||||
|
"""
|
||||||
|
Args:
|
||||||
|
versions (dict): Dictionary like ``{'namespace': 'v1.0.0'}`` used to specify that this provider should always
|
||||||
|
return models from a specific version of a namespace (unless explicitly requested otherwise
|
||||||
|
in a call to :meth:`.get` ).
|
||||||
|
**kwargs: passed to superclass __init__ (see :class:`.Provider` )
|
||||||
|
"""
|
||||||
|
self.versions = versions
|
||||||
|
super(SchemaProvider, self).__init__(**kwargs)
|
||||||
|
|
||||||
@property
|
@property
|
||||||
def path(self) -> Path:
|
def path(self) -> Path:
|
||||||
return self.config.cache_dir
|
return self.config.cache_dir
|
||||||
|
@ -737,6 +757,9 @@ class SchemaProvider(Provider):
|
||||||
|
|
||||||
Wrapper around :meth:`.PydanticProvider.get`
|
Wrapper around :meth:`.PydanticProvider.get`
|
||||||
"""
|
"""
|
||||||
|
if version is None and self.versions is not None:
|
||||||
|
version = self.versions.get(namespace, None)
|
||||||
|
|
||||||
return PydanticProvider(path=self.path).get(namespace, version)
|
return PydanticProvider(path=self.path).get(namespace, version)
|
||||||
|
|
||||||
def get_class(self, namespace: str, class_: str, version: Optional[str] = None) -> Type[BaseModel]:
|
def get_class(self, namespace: str, class_: str, version: Optional[str] = None) -> Type[BaseModel]:
|
||||||
|
@ -745,6 +768,9 @@ class SchemaProvider(Provider):
|
||||||
|
|
||||||
Wrapper around :meth:`.PydanticProvider.get_class`
|
Wrapper around :meth:`.PydanticProvider.get_class`
|
||||||
"""
|
"""
|
||||||
|
if version is None and self.versions is not None:
|
||||||
|
version = self.versions.get(namespace, None)
|
||||||
|
|
||||||
return PydanticProvider(path=self.path).get_class(namespace, class_, version)
|
return PydanticProvider(path=self.path).get_class(namespace, class_, version)
|
||||||
|
|
||||||
|
|
||||||
|
|
BIN
nwb_linkml/tests/data/aibs_ecephys.nwb
Normal file
BIN
nwb_linkml/tests/data/aibs_ecephys.nwb
Normal file
Binary file not shown.
4
nwb_linkml/tests/data/sources.txt
Normal file
4
nwb_linkml/tests/data/sources.txt
Normal file
|
@ -0,0 +1,4 @@
|
||||||
|
aibs_ecephys.nwb
|
||||||
|
- https://dandiarchive.org/dandiset/000021/
|
||||||
|
- 000021/sub-738651046/sub-738651046_ses-760693773_probe-769322820_ecephys.nwb
|
||||||
|
- truncated datasets to length 10
|
|
@ -1,11 +1,14 @@
|
||||||
import pdb
|
import pdb
|
||||||
|
import h5py
|
||||||
|
|
||||||
import pytest
|
import pytest
|
||||||
from pathlib import Path
|
from pathlib import Path
|
||||||
|
import numpy as np
|
||||||
|
|
||||||
from ..fixtures import tmp_output_dir, set_config_vars
|
from ..fixtures import tmp_output_dir, set_config_vars
|
||||||
|
|
||||||
from nwb_linkml.io.hdf5 import HDF5IO
|
from nwb_linkml.io.hdf5 import HDF5IO
|
||||||
|
from nwb_linkml.io.hdf5 import truncate_file
|
||||||
@pytest.mark.skip()
|
@pytest.mark.skip()
|
||||||
def test_hdf_read():
|
def test_hdf_read():
|
||||||
NWBFILE = Path('/Users/jonny/Dropbox/lab/p2p_ld/data/nwb/sub-738651046_ses-760693773.nwb')
|
NWBFILE = Path('/Users/jonny/Dropbox/lab/p2p_ld/data/nwb/sub-738651046_ses-760693773.nwb')
|
||||||
|
@ -15,3 +18,73 @@ def test_hdf_read():
|
||||||
model = io.read('acquisition')
|
model = io.read('acquisition')
|
||||||
|
|
||||||
pdb.set_trace()
|
pdb.set_trace()
|
||||||
|
|
||||||
|
@pytest.mark.skip()
|
||||||
|
def test_truncate_file(tmp_output_dir):
|
||||||
|
source = tmp_output_dir / 'truncate_source.hdf5'
|
||||||
|
|
||||||
|
# create a dang ol hdf5 file with a big dataset and some softlinks and make sure
|
||||||
|
# we truncate the dataset and preserve softlink
|
||||||
|
|
||||||
|
h5f = h5py.File(str(source), 'w')
|
||||||
|
data_group = h5f.create_group('data')
|
||||||
|
dataset_contig = h5f.create_dataset(
|
||||||
|
'/data/dataset_contig',
|
||||||
|
data=np.zeros((1000,30,40), dtype=np.float64),
|
||||||
|
compression = "gzip",
|
||||||
|
compression_opts = 9
|
||||||
|
)
|
||||||
|
dataset_chunked = h5f.create_dataset(
|
||||||
|
'/data/dataset_chunked',
|
||||||
|
data=np.zeros((1000, 40, 50), dtype=np.float64),
|
||||||
|
compression="gzip",
|
||||||
|
compression_opts=9,
|
||||||
|
chunks=True
|
||||||
|
)
|
||||||
|
dataset_contig.attrs['reference_other'] = dataset_chunked.ref
|
||||||
|
dataset_chunked.attrs['reference_other'] = dataset_contig.ref
|
||||||
|
dataset_contig.attrs['anattr'] = 1
|
||||||
|
|
||||||
|
link_group = h5f.create_group('link/child')
|
||||||
|
link_group.attrs['reference_contig'] = dataset_contig.ref
|
||||||
|
link_group.attrs['reference_chunked'] = dataset_chunked.ref
|
||||||
|
h5f.flush()
|
||||||
|
h5f.close()
|
||||||
|
|
||||||
|
source_size = source.stat().st_size
|
||||||
|
|
||||||
|
# do it without providing target to check that we make filename correctly
|
||||||
|
n = 10
|
||||||
|
target_output = truncate_file(source, n=n)
|
||||||
|
assert target_output == source.parent / (source.stem + '_truncated.hdf5')
|
||||||
|
# check that we actually made it smaller
|
||||||
|
target_size = target_output.stat().st_size
|
||||||
|
# empirically, the source dataset is ~125KB and truncated is ~17KB
|
||||||
|
assert target_size < source_size / 5
|
||||||
|
|
||||||
|
# then check that we have what's expected in the file
|
||||||
|
target_h5f = h5py.File(target_output, 'r')
|
||||||
|
|
||||||
|
# truncation happened
|
||||||
|
assert target_h5f['data']['dataset_contig'].shape == (n, 30, 40)
|
||||||
|
assert target_h5f['data']['dataset_chunked'].shape == (n, 40, 50)
|
||||||
|
# references still work
|
||||||
|
# can't directly assess object identity equality with "is"
|
||||||
|
# so this tests if the referenced dereference and that they dereference to the right place
|
||||||
|
assert target_h5f[target_h5f['data']['dataset_contig'].attrs['reference_other']].name == target_h5f['data']['dataset_chunked'].name
|
||||||
|
assert target_h5f[target_h5f['data']['dataset_chunked'].attrs['reference_other']].name == target_h5f['data']['dataset_contig'].name
|
||||||
|
assert target_h5f[target_h5f['link']['child'].attrs['reference_contig']].name == target_h5f['data']['dataset_contig'].name
|
||||||
|
assert target_h5f[target_h5f['link']['child'].attrs['reference_chunked']].name == target_h5f['data']['dataset_chunked'].name
|
||||||
|
assert target_h5f['data']['dataset_contig'].attrs['anattr'] == 1
|
||||||
|
|
||||||
|
@pytest.mark.skip()
|
||||||
|
def test_flatten_hdf():
|
||||||
|
from nwb_linkml.io.hdf5 import HDF5IO, flatten_hdf
|
||||||
|
path = '/Users/jonny/Dropbox/lab/p2p_ld/data/nwb/sub-738651046_ses-760693773_probe-769322820_ecephys.nwb'
|
||||||
|
import h5py
|
||||||
|
h5f = h5py.File(path)
|
||||||
|
flat = flatten_hdf(h5f)
|
||||||
|
assert not any(['specifications' in v.path for v in flat.values()])
|
||||||
|
|
||||||
|
raise NotImplementedError('Just a stub for local testing for now, finish me!')
|
||||||
|
|
||||||
|
|
|
@ -1,6 +1,8 @@
|
||||||
import pdb
|
import pdb
|
||||||
import shutil
|
import shutil
|
||||||
import os
|
import os
|
||||||
|
import sys
|
||||||
|
from pathlib import Path
|
||||||
|
|
||||||
from typing import Optional, Union, List
|
from typing import Optional, Union, List
|
||||||
from ..fixtures import tmp_output_dir, set_config_vars
|
from ..fixtures import tmp_output_dir, set_config_vars
|
||||||
|
@ -8,6 +10,8 @@ from ..fixtures import tmp_output_dir, set_config_vars
|
||||||
import pytest
|
import pytest
|
||||||
|
|
||||||
from nwb_linkml.providers.schema import LinkMLProvider, PydanticProvider
|
from nwb_linkml.providers.schema import LinkMLProvider, PydanticProvider
|
||||||
|
import nwb_linkml
|
||||||
|
from nwb_linkml.maps.naming import version_module_case
|
||||||
|
|
||||||
|
|
||||||
CORE_MODULES = (
|
CORE_MODULES = (
|
||||||
|
@ -62,14 +66,24 @@ def test_linkml_provider(tmp_output_dir, repo_version, schema_version, schema_di
|
||||||
})
|
})
|
||||||
]
|
]
|
||||||
)
|
)
|
||||||
def test_pydantic_provider(tmp_output_dir, class_name, test_fields):
|
def test_pydantic_provider_core(tmp_output_dir, class_name, test_fields):
|
||||||
provider = PydanticProvider(path=tmp_output_dir)
|
provider = PydanticProvider(path=tmp_output_dir)
|
||||||
# clear any prior output
|
# clear any prior output
|
||||||
assert provider.path.parent == tmp_output_dir
|
assert provider.path.parent == tmp_output_dir
|
||||||
shutil.rmtree(provider.path, ignore_errors=True)
|
shutil.rmtree(provider.path, ignore_errors=True)
|
||||||
assert not provider.path.exists()
|
assert not provider.path.exists()
|
||||||
|
|
||||||
core = provider.get('core')
|
# first, we should not build if we're allowed to get core from repo
|
||||||
|
core = provider.get('core', allow_repo=True)
|
||||||
|
assert Path(nwb_linkml.__file__).parent in Path(core.__file__).parents
|
||||||
|
assert not (provider.path / 'core').exists()
|
||||||
|
|
||||||
|
# then, if we're not allowed to get repo versions, we build!
|
||||||
|
del sys.modules[core.__name__]
|
||||||
|
core = provider.get('core', allow_repo=False)
|
||||||
|
# ensure we didn't get the builtin one
|
||||||
|
assert Path(nwb_linkml.__file__).parent not in Path(core.__file__).parents
|
||||||
|
assert (tmp_output_dir / 'pydantic' / 'core' / version_module_case(core.version) / 'namespace.py').exists()
|
||||||
|
|
||||||
test_class = getattr(core, class_name)
|
test_class = getattr(core, class_name)
|
||||||
assert test_class == provider.get_class('core', class_name)
|
assert test_class == provider.get_class('core', class_name)
|
||||||
|
|
Loading…
Reference in a new issue