Fix custom plugin downloaders
Change get_as_dataframe call signature
This commit is contained in:
parent
08c53cf894
commit
52e1d2135b
9 changed files with 156 additions and 105 deletions
107
pdm.lock
generated
107
pdm.lock
generated
|
@ -5,7 +5,7 @@
|
|||
groups = ["default", "dev", "mqtt"]
|
||||
strategy = ["cross_platform"]
|
||||
lock_version = "4.4.1"
|
||||
content_hash = "sha256:07dee91945ef2f5557c7130b7ab9fee6bbba2763ce65a3cc18f0d3c89429c30f"
|
||||
content_hash = "sha256:0da68c7fed8db7a12e36002b8d6194c1651f9653fc7fbf7797c553774c9dbf32"
|
||||
|
||||
[[package]]
|
||||
name = "aiomqtt"
|
||||
|
@ -380,17 +380,17 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "fastapi"
|
||||
version = "0.110.0"
|
||||
version = "0.110.1"
|
||||
requires_python = ">=3.8"
|
||||
summary = "FastAPI framework, high performance, easy to learn, fast to code, ready for production"
|
||||
dependencies = [
|
||||
"pydantic!=1.8,!=1.8.1,!=2.0.0,!=2.0.1,!=2.1.0,<3.0.0,>=1.7.4",
|
||||
"starlette<0.37.0,>=0.36.3",
|
||||
"starlette<0.38.0,>=0.37.2",
|
||||
"typing-extensions>=4.8.0",
|
||||
]
|
||||
files = [
|
||||
{file = "fastapi-0.110.0-py3-none-any.whl", hash = "sha256:87a1f6fb632a218222c5984be540055346a8f5d8a68e8f6fb647b1dc9934de4b"},
|
||||
{file = "fastapi-0.110.0.tar.gz", hash = "sha256:266775f0dcc95af9d3ef39bad55cff525329a931d5fd51930aadd4f428bf7ff3"},
|
||||
{file = "fastapi-0.110.1-py3-none-any.whl", hash = "sha256:5df913203c482f820d31f48e635e022f8cbfe7350e4830ef05a3163925b1addc"},
|
||||
{file = "fastapi-0.110.1.tar.gz", hash = "sha256:6feac43ec359dfe4f45b2c18ec8c94edb8dc2dfc461d417d9e626590c071baad"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -447,7 +447,7 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "geoalchemy2"
|
||||
version = "0.14.6"
|
||||
version = "0.14.7"
|
||||
requires_python = ">=3.7"
|
||||
summary = "Using SQLAlchemy with Spatial Databases"
|
||||
dependencies = [
|
||||
|
@ -455,8 +455,8 @@ dependencies = [
|
|||
"packaging",
|
||||
]
|
||||
files = [
|
||||
{file = "GeoAlchemy2-0.14.6-py3-none-any.whl", hash = "sha256:649c70f9275aded0341ed0c879e140d77c16ec33023cc21352de2eb7bb5fd509"},
|
||||
{file = "GeoAlchemy2-0.14.6.tar.gz", hash = "sha256:e940681a60571d692124f687ecfe605164675341dbbaf5adf5f0ee46932c337b"},
|
||||
{file = "GeoAlchemy2-0.14.7-py3-none-any.whl", hash = "sha256:af592892c58da0b98aa284d400f207f08a643aeee4523f025cef74991f76af14"},
|
||||
{file = "GeoAlchemy2-0.14.7.tar.gz", hash = "sha256:9ff731c4e5b955525cb128ee7173222365e7f084d4b99f6f68e491bac6b44d21"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -638,7 +638,7 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "matplotlib"
|
||||
version = "3.8.3"
|
||||
version = "3.8.4"
|
||||
requires_python = ">=3.9"
|
||||
summary = "Python plotting package"
|
||||
dependencies = [
|
||||
|
@ -646,29 +646,29 @@ dependencies = [
|
|||
"cycler>=0.10",
|
||||
"fonttools>=4.22.0",
|
||||
"kiwisolver>=1.3.1",
|
||||
"numpy<2,>=1.21",
|
||||
"numpy>=1.21",
|
||||
"packaging>=20.0",
|
||||
"pillow>=8",
|
||||
"pyparsing>=2.3.1",
|
||||
"python-dateutil>=2.7",
|
||||
]
|
||||
files = [
|
||||
{file = "matplotlib-3.8.3-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:5184e07c7e1d6d1481862ee361905b7059f7fe065fc837f7c3dc11eeb3f2f900"},
|
||||
{file = "matplotlib-3.8.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:d7e7e0993d0758933b1a241a432b42c2db22dfa37d4108342ab4afb9557cbe3e"},
|
||||
{file = "matplotlib-3.8.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04b36ad07eac9740fc76c2aa16edf94e50b297d6eb4c081e3add863de4bb19a7"},
|
||||
{file = "matplotlib-3.8.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7c42dae72a62f14982f1474f7e5c9959fc4bc70c9de11cc5244c6e766200ba65"},
|
||||
{file = "matplotlib-3.8.3-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bf5932eee0d428192c40b7eac1399d608f5d995f975cdb9d1e6b48539a5ad8d0"},
|
||||
{file = "matplotlib-3.8.3-cp311-cp311-win_amd64.whl", hash = "sha256:40321634e3a05ed02abf7c7b47a50be50b53ef3eaa3a573847431a545585b407"},
|
||||
{file = "matplotlib-3.8.3-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:09074f8057917d17ab52c242fdf4916f30e99959c1908958b1fc6032e2d0f6d4"},
|
||||
{file = "matplotlib-3.8.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:5745f6d0fb5acfabbb2790318db03809a253096e98c91b9a31969df28ee604aa"},
|
||||
{file = "matplotlib-3.8.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b97653d869a71721b639714b42d87cda4cfee0ee74b47c569e4874c7590c55c5"},
|
||||
{file = "matplotlib-3.8.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:242489efdb75b690c9c2e70bb5c6550727058c8a614e4c7716f363c27e10bba1"},
|
||||
{file = "matplotlib-3.8.3-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:83c0653c64b73926730bd9ea14aa0f50f202ba187c307a881673bad4985967b7"},
|
||||
{file = "matplotlib-3.8.3-cp312-cp312-win_amd64.whl", hash = "sha256:ef6c1025a570354297d6c15f7d0f296d95f88bd3850066b7f1e7b4f2f4c13a39"},
|
||||
{file = "matplotlib-3.8.3-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:fa93695d5c08544f4a0dfd0965f378e7afc410d8672816aff1e81be1f45dbf2e"},
|
||||
{file = "matplotlib-3.8.3-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9764df0e8778f06414b9d281a75235c1e85071f64bb5d71564b97c1306a2afc"},
|
||||
{file = "matplotlib-3.8.3-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:5e431a09e6fab4012b01fc155db0ce6dccacdbabe8198197f523a4ef4805eb26"},
|
||||
{file = "matplotlib-3.8.3.tar.gz", hash = "sha256:7b416239e9ae38be54b028abbf9048aff5054a9aba5416bef0bd17f9162ce161"},
|
||||
{file = "matplotlib-3.8.4-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:72f9322712e4562e792b2961971891b9fbbb0e525011e09ea0d1f416c4645661"},
|
||||
{file = "matplotlib-3.8.4-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:232ce322bfd020a434caaffbd9a95333f7c2491e59cfc014041d95e38ab90d1c"},
|
||||
{file = "matplotlib-3.8.4-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6addbd5b488aedb7f9bc19f91cd87ea476206f45d7116fcfe3d31416702a82fa"},
|
||||
{file = "matplotlib-3.8.4-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc4ccdc64e3039fc303defd119658148f2349239871db72cd74e2eeaa9b80b71"},
|
||||
{file = "matplotlib-3.8.4-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:b7a2a253d3b36d90c8993b4620183b55665a429da8357a4f621e78cd48b2b30b"},
|
||||
{file = "matplotlib-3.8.4-cp311-cp311-win_amd64.whl", hash = "sha256:8080d5081a86e690d7688ffa542532e87f224c38a6ed71f8fbed34dd1d9fedae"},
|
||||
{file = "matplotlib-3.8.4-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:6485ac1f2e84676cff22e693eaa4fbed50ef5dc37173ce1f023daef4687df616"},
|
||||
{file = "matplotlib-3.8.4-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c89ee9314ef48c72fe92ce55c4e95f2f39d70208f9f1d9db4e64079420d8d732"},
|
||||
{file = "matplotlib-3.8.4-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:50bac6e4d77e4262c4340d7a985c30912054745ec99756ce213bfbc3cb3808eb"},
|
||||
{file = "matplotlib-3.8.4-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f51c4c869d4b60d769f7b4406eec39596648d9d70246428745a681c327a8ad30"},
|
||||
{file = "matplotlib-3.8.4-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:b12ba985837e4899b762b81f5b2845bd1a28f4fdd1a126d9ace64e9c4eb2fb25"},
|
||||
{file = "matplotlib-3.8.4-cp312-cp312-win_amd64.whl", hash = "sha256:7a6769f58ce51791b4cb8b4d7642489df347697cd3e23d88266aaaee93b41d9a"},
|
||||
{file = "matplotlib-3.8.4-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:c7064120a59ce6f64103c9cefba8ffe6fba87f2c61d67c401186423c9a20fd35"},
|
||||
{file = "matplotlib-3.8.4-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a0e47eda4eb2614300fc7bb4657fced3e83d6334d03da2173b09e447418d499f"},
|
||||
{file = "matplotlib-3.8.4-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:493e9f6aa5819156b58fce42b296ea31969f2aab71c5b680b4ea7a3cb5c07d94"},
|
||||
{file = "matplotlib-3.8.4.tar.gz", hash = "sha256:8aac397d5e9ec158960e31c381c5ffc52ddd52bd9a47717e2a694038167dffea"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -712,30 +712,31 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "orjson"
|
||||
version = "3.9.15"
|
||||
version = "3.10.0"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Fast, correct Python JSON library supporting dataclasses, datetimes, and numpy"
|
||||
files = [
|
||||
{file = "orjson-3.9.15-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:c8e8fe01e435005d4421f183038fc70ca85d2c1e490f51fb972db92af6e047c2"},
|
||||
{file = "orjson-3.9.15-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:87f1097acb569dde17f246faa268759a71a2cb8c96dd392cd25c668b104cad2f"},
|
||||
{file = "orjson-3.9.15-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ff0f9913d82e1d1fadbd976424c316fbc4d9c525c81d047bbdd16bd27dd98cfc"},
|
||||
{file = "orjson-3.9.15-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8055ec598605b0077e29652ccfe9372247474375e0e3f5775c91d9434e12d6b1"},
|
||||
{file = "orjson-3.9.15-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d6768a327ea1ba44c9114dba5fdda4a214bdb70129065cd0807eb5f010bfcbb5"},
|
||||
{file = "orjson-3.9.15-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:12365576039b1a5a47df01aadb353b68223da413e2e7f98c02403061aad34bde"},
|
||||
{file = "orjson-3.9.15-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:71c6b009d431b3839d7c14c3af86788b3cfac41e969e3e1c22f8a6ea13139404"},
|
||||
{file = "orjson-3.9.15-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e18668f1bd39e69b7fed19fa7cd1cd110a121ec25439328b5c89934e6d30d357"},
|
||||
{file = "orjson-3.9.15-cp311-none-win32.whl", hash = "sha256:62482873e0289cf7313461009bf62ac8b2e54bc6f00c6fabcde785709231a5d7"},
|
||||
{file = "orjson-3.9.15-cp311-none-win_amd64.whl", hash = "sha256:b3d336ed75d17c7b1af233a6561cf421dee41d9204aa3cfcc6c9c65cd5bb69a8"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:82425dd5c7bd3adfe4e94c78e27e2fa02971750c2b7ffba648b0f5d5cc016a73"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2c51378d4a8255b2e7c1e5cc430644f0939539deddfa77f6fac7b56a9784160a"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:6ae4e06be04dc00618247c4ae3f7c3e561d5bc19ab6941427f6d3722a0875ef7"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bcef128f970bb63ecf9a65f7beafd9b55e3aaf0efc271a4154050fc15cdb386e"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b72758f3ffc36ca566ba98a8e7f4f373b6c17c646ff8ad9b21ad10c29186f00d"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10c57bc7b946cf2efa67ac55766e41764b66d40cbd9489041e637c1304400494"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:946c3a1ef25338e78107fba746f299f926db408d34553b4754e90a7de1d44068"},
|
||||
{file = "orjson-3.9.15-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2f256d03957075fcb5923410058982aea85455d035607486ccb847f095442bda"},
|
||||
{file = "orjson-3.9.15-cp312-none-win_amd64.whl", hash = "sha256:5bb399e1b49db120653a31463b4a7b27cf2fbfe60469546baf681d1b39f4edf2"},
|
||||
{file = "orjson-3.9.15.tar.gz", hash = "sha256:95cae920959d772f30ab36d3b25f83bb0f3be671e986c72ce22f8fa700dae061"},
|
||||
{file = "orjson-3.10.0-cp311-cp311-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:9587053e0cefc284e4d1cd113c34468b7d3f17666d22b185ea654f0775316a26"},
|
||||
{file = "orjson-3.10.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1bef1050b1bdc9ea6c0d08468e3e61c9386723633b397e50b82fda37b3563d72"},
|
||||
{file = "orjson-3.10.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d16c6963ddf3b28c0d461641517cd312ad6b3cf303d8b87d5ef3fa59d6844337"},
|
||||
{file = "orjson-3.10.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4251964db47ef090c462a2d909f16c7c7d5fe68e341dabce6702879ec26d1134"},
|
||||
{file = "orjson-3.10.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:73bbbdc43d520204d9ef0817ac03fa49c103c7f9ea94f410d2950755be2c349c"},
|
||||
{file = "orjson-3.10.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:414e5293b82373606acf0d66313aecb52d9c8c2404b1900683eb32c3d042dbd7"},
|
||||
{file = "orjson-3.10.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:feaed5bb09877dc27ed0d37f037ddef6cb76d19aa34b108db270d27d3d2ef747"},
|
||||
{file = "orjson-3.10.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5127478260db640323cea131ee88541cb1a9fbce051f0b22fa2f0892f44da302"},
|
||||
{file = "orjson-3.10.0-cp311-none-win32.whl", hash = "sha256:b98345529bafe3c06c09996b303fc0a21961820d634409b8639bc16bd4f21b63"},
|
||||
{file = "orjson-3.10.0-cp311-none-win_amd64.whl", hash = "sha256:658ca5cee3379dd3d37dbacd43d42c1b4feee99a29d847ef27a1cb18abdfb23f"},
|
||||
{file = "orjson-3.10.0-cp312-cp312-macosx_10_15_x86_64.macosx_11_0_arm64.macosx_10_15_universal2.whl", hash = "sha256:4329c1d24fd130ee377e32a72dc54a3c251e6706fccd9a2ecb91b3606fddd998"},
|
||||
{file = "orjson-3.10.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ef0f19fdfb6553342b1882f438afd53c7cb7aea57894c4490c43e4431739c700"},
|
||||
{file = "orjson-3.10.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c4f60db24161534764277f798ef53b9d3063092f6d23f8f962b4a97edfa997a0"},
|
||||
{file = "orjson-3.10.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1de3fd5c7b208d836f8ecb4526995f0d5877153a4f6f12f3e9bf11e49357de98"},
|
||||
{file = "orjson-3.10.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f93e33f67729d460a177ba285002035d3f11425ed3cebac5f6ded4ef36b28344"},
|
||||
{file = "orjson-3.10.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:237ba922aef472761acd697eef77fef4831ab769a42e83c04ac91e9f9e08fa0e"},
|
||||
{file = "orjson-3.10.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:98c1bfc6a9bec52bc8f0ab9b86cc0874b0299fccef3562b793c1576cf3abb570"},
|
||||
{file = "orjson-3.10.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:30d795a24be16c03dca0c35ca8f9c8eaaa51e3342f2c162d327bd0225118794a"},
|
||||
{file = "orjson-3.10.0-cp312-none-win32.whl", hash = "sha256:6a3f53dc650bc860eb26ec293dfb489b2f6ae1cbfc409a127b01229980e372f7"},
|
||||
{file = "orjson-3.10.0-cp312-none-win_amd64.whl", hash = "sha256:983db1f87c371dc6ffc52931eb75f9fe17dc621273e43ce67bee407d3e5476e9"},
|
||||
{file = "orjson-3.10.0.tar.gz", hash = "sha256:ba4d8cac5f2e2cff36bea6b6481cdb92b38c202bcec603d6f5ff91960595a1ed"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1401,15 +1402,15 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "starlette"
|
||||
version = "0.36.3"
|
||||
version = "0.37.2"
|
||||
requires_python = ">=3.8"
|
||||
summary = "The little ASGI library that shines."
|
||||
dependencies = [
|
||||
"anyio<5,>=3.4.0",
|
||||
]
|
||||
files = [
|
||||
{file = "starlette-0.36.3-py3-none-any.whl", hash = "sha256:13d429aa93a61dc40bf503e8c801db1f1bca3dc706b10ef2434a36123568f044"},
|
||||
{file = "starlette-0.36.3.tar.gz", hash = "sha256:90a671733cfb35771d8cc605e0b679d23b992f8dcfad48cc60b38cb29aeb7080"},
|
||||
{file = "starlette-0.37.2-py3-none-any.whl", hash = "sha256:6fe59f29268538e5d0d182f2791a479a0c64638e6935d1c6989e63fb2699c6ee"},
|
||||
{file = "starlette-0.37.2.tar.gz", hash = "sha256:9af890290133b79fc3db55474ade20f6220a364a0402e0b556e7cd5e1e093823"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
@ -1434,12 +1435,12 @@ files = [
|
|||
|
||||
[[package]]
|
||||
name = "types-passlib"
|
||||
version = "1.7.7.20240311"
|
||||
version = "1.7.7.20240327"
|
||||
requires_python = ">=3.8"
|
||||
summary = "Typing stubs for passlib"
|
||||
files = [
|
||||
{file = "types-passlib-1.7.7.20240311.tar.gz", hash = "sha256:287dd27cec5421daf6be5c295f681baf343c146038c8bde4db783bcac1beccb7"},
|
||||
{file = "types_passlib-1.7.7.20240311-py3-none-any.whl", hash = "sha256:cd44166e9347ae516f4830046cd1673c1ef90a5cc7ddd1356cf8a14892f29249"},
|
||||
{file = "types-passlib-1.7.7.20240327.tar.gz", hash = "sha256:4cce6a1a3a6afee9fc4728b4d9784300764ac2be747f5bcc01646d904b85f4bb"},
|
||||
{file = "types_passlib-1.7.7.20240327-py3-none-any.whl", hash = "sha256:3a3b7f4258b71034d2e2f4f307d6810f9904f906cdf375514c8bdbdb28a4ad23"},
|
||||
]
|
||||
|
||||
[[package]]
|
||||
|
|
|
@ -8,7 +8,7 @@ authors = [
|
|||
dependencies = [
|
||||
"apscheduler>=3.10.4",
|
||||
"asyncpg>=0.28.0",
|
||||
"fastapi>=0.110",
|
||||
"fastapi>=0.110.1",
|
||||
"geoalchemy2>=0.14.2",
|
||||
"geopandas>=0.14.0",
|
||||
"itsdangerous>=2.1.2",
|
||||
|
|
|
@ -1 +1 @@
|
|||
__version__: str = '2023.4.dev56+g775030d.d20240325'
|
||||
__version__: str = '2023.4.dev62+g08c53cf.d20240405'
|
|
@ -9,11 +9,13 @@ from sqlalchemy.orm import selectinload, joinedload
|
|||
|
||||
from gisaf.database import pandas_query, fastapi_db_session as db_session
|
||||
from gisaf.models.geo_models_base import GeoModel, PlottableModel
|
||||
from gisaf.models.info import Downloader
|
||||
from gisaf.security import (
|
||||
Token, authenticate_user, get_current_active_user, create_access_token,
|
||||
)
|
||||
from gisaf.models.authentication import (User, UserRead, Role, RoleRead)
|
||||
from gisaf.registry import registry, NotInRegistry
|
||||
from gisaf.plugins import DownloadResponse, manager as plugin_manager
|
||||
|
||||
logger = logging.getLogger(__name__)
|
||||
|
||||
|
@ -47,7 +49,8 @@ async def download_csv(
|
|||
if custom_getter:
|
||||
df = await custom_getter(model_id)
|
||||
else:
|
||||
df = await values_model.get_as_dataframe(model_id=model_id, with_only_columns=[value])
|
||||
item = await db_session.get(model, model_id)
|
||||
df = await values_model.get_as_dataframe(item=item, with_only_columns=[value])
|
||||
if len(df) == 0:
|
||||
raise HTTPException(status.HTTP_204_NO_CONTENT)
|
||||
if resample and resample != '0':
|
||||
|
@ -75,3 +78,49 @@ async def download_csv(
|
|||
'Content-Disposition': f"attachment; filename={filename}"
|
||||
})
|
||||
return response
|
||||
|
||||
|
||||
@api.get('/plugin/{name}/{store}/{id}')
|
||||
async def execute_action(
|
||||
name: str,
|
||||
store: str,
|
||||
id: int,
|
||||
db_session: db_session,
|
||||
user: Annotated[UserRead, Depends(get_current_active_user)]
|
||||
):
|
||||
"""
|
||||
Download the result of an action
|
||||
"""
|
||||
## TODO: implement permissions for actions
|
||||
#await check_permission(info.context['request'], 'action')
|
||||
try:
|
||||
store_record = registry.stores.loc[store]
|
||||
model: type[GeoModel] = store_record.model
|
||||
values_model = registry.values_for_model[model][0]
|
||||
except KeyError:
|
||||
raise HTTPException(status_code=status.HTTP_404_NOT_FOUND)
|
||||
item = await db_session.get(model, id)
|
||||
dls: list[Downloader] = [dl for dl in plugin_manager.downloaders_stores[store]
|
||||
if dl.name == name]
|
||||
if len(dls) == 0:
|
||||
raise HTTPException(status.HTTP_501_NOT_IMPLEMENTED,
|
||||
detail=f'No downloader {name} for {store}')
|
||||
elif len(dls) > 1:
|
||||
raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f'Too many downloaders ({len(dls)}) {name} for {store}')
|
||||
downloader = dls[0]
|
||||
result: DownloadResponse
|
||||
try:
|
||||
result = await downloader._plugin.execute(model, item)
|
||||
except Exception as err:
|
||||
logging.exception(err)
|
||||
raise HTTPException(status.HTTP_500_INTERNAL_SERVER_ERROR,
|
||||
detail=f'Error in action: {err.args[0]}'
|
||||
)
|
||||
return StreamingResponse(
|
||||
iter([result.content]),
|
||||
headers = {
|
||||
'Content-Disposition': f'attachment; filename="{result.file_name}"'
|
||||
},
|
||||
media_type=result.content_type,
|
||||
)
|
|
@ -178,11 +178,14 @@ async def get_model_list(
|
|||
return resp
|
||||
|
||||
@api.get('/{store_name}/values/{value}')
|
||||
async def get_model_values(store_name: str, value: str,
|
||||
response: Response,
|
||||
where: str,
|
||||
resample: str | None = None,
|
||||
):
|
||||
async def get_model_values(
|
||||
db_session: db_session,
|
||||
store_name: str,
|
||||
value: str,
|
||||
response: Response,
|
||||
where: str,
|
||||
resample: str | None = None,
|
||||
):
|
||||
"""
|
||||
Get values
|
||||
"""
|
||||
|
@ -202,7 +205,8 @@ async def get_model_values(store_name: str, value: str,
|
|||
if getter:
|
||||
df = await getter(model_id)
|
||||
else:
|
||||
df = await values_model.get_as_dataframe(model_id=model_id,
|
||||
item = await db_session.get(model, model_id)
|
||||
df = await values_model.get_as_dataframe(item=item,
|
||||
with_only_columns=[value])
|
||||
|
||||
if len(df) == 0:
|
||||
|
|
|
@ -15,7 +15,7 @@ from gisaf.api.admin import api as admin_api
|
|||
from gisaf.api.dashboard import api as dashboard_api
|
||||
from gisaf.api.map import api as map_api
|
||||
from gisaf.api.download import api as download_api
|
||||
from gisaf.plugins import manager as plugin_manger
|
||||
from gisaf.plugins import manager as plugin_manager
|
||||
|
||||
logging.basicConfig(level=conf.gisaf.debugLevel)
|
||||
logger = logging.getLogger(__name__)
|
||||
|
@ -27,7 +27,7 @@ async def lifespan(app: FastAPI):
|
|||
await setup_redis()
|
||||
await setup_redis_cache()
|
||||
await setup_live()
|
||||
await plugin_manger.scan_plugins()
|
||||
await plugin_manager.scan_plugins()
|
||||
await admin_manager.setup_admin()
|
||||
await map_tile_registry.setup()
|
||||
yield
|
||||
|
|
|
@ -1130,44 +1130,31 @@ class PlottableModel(Model):
|
|||
values: ClassVar[list[dict[str, str]]] = []
|
||||
|
||||
@classmethod
|
||||
async def get_as_dataframe(cls, model_id=None, where=None, **kwargs):
|
||||
async def get_as_dataframe(cls, item, where=None, **kwargs):
|
||||
"""
|
||||
Get a dataframe for the data.
|
||||
It's quite generic, so subclasses might want to subclass this.
|
||||
"""
|
||||
if where is None:
|
||||
if model_id is None:
|
||||
where_ = None
|
||||
else:
|
||||
where_ = cls.ref_id == model_id
|
||||
else:
|
||||
if model_id is None:
|
||||
where_ = where
|
||||
else:
|
||||
where_ = and_(cls.ref_id == model_id, where)
|
||||
|
||||
if where_ is not None:
|
||||
df = await cls.get_df(where=where_, **kwargs)
|
||||
else:
|
||||
df = await cls.get_df(**kwargs)
|
||||
|
||||
return df
|
||||
where_ = cls.ref_id == item.id
|
||||
if where is not None:
|
||||
where_ = and_(where_, where)
|
||||
return await cls.get_df(where=where_, **kwargs)
|
||||
|
||||
|
||||
class TimePlottableModel(PlottableModel):
|
||||
time: datetime
|
||||
|
||||
@classmethod
|
||||
async def get_as_dataframe(cls, model_id=None, with_only_columns=None, **kwargs):
|
||||
async def get_as_dataframe(cls, item, with_only_columns=None, **kwargs):
|
||||
"""
|
||||
Get the data as a time-indexed dataframe
|
||||
"""
|
||||
if with_only_columns == None:
|
||||
if with_only_columns is None:
|
||||
with_only_columns = [val['name'] for val in cls.values]
|
||||
if 'time' not in with_only_columns:
|
||||
with_only_columns.insert(0, 'time')
|
||||
|
||||
df = await super().get_as_dataframe(model_id=model_id,
|
||||
df = await super().get_as_dataframe(item=item,
|
||||
with_only_columns=with_only_columns,
|
||||
**kwargs)
|
||||
|
||||
|
|
|
@ -1,6 +1,6 @@
|
|||
from typing import Any
|
||||
|
||||
from pydantic import BaseModel
|
||||
from pydantic import BaseModel, PrivateAttr
|
||||
|
||||
from gisaf.models.info_item import Tag, InfoItem
|
||||
from gisaf.models.tags import Tags
|
||||
|
@ -112,11 +112,15 @@ class ActionAction(BaseModel):
|
|||
|
||||
|
||||
class Downloader(BaseModel):
|
||||
# plugin: str
|
||||
# downloader: str
|
||||
_plugin: Any = PrivateAttr() # DownloadPlugin
|
||||
roles: list[str] = []
|
||||
name: str
|
||||
icon: str | None = None
|
||||
icon: str | None
|
||||
|
||||
def __init__(self, _plugin, **data):
|
||||
super().__init__(**data)
|
||||
# We generate the value for our private attribute
|
||||
self._plugin = _plugin
|
||||
|
||||
|
||||
class LegendItem(BaseModel):
|
||||
|
|
|
@ -12,9 +12,9 @@ from fastapi import HTTPException, status
|
|||
from sqlalchemy import or_, and_
|
||||
# from geoalchemy2.shape import to_shape, from_shape
|
||||
# from graphene import ObjectType, String, List, Boolean, Field, Float, InputObjectType
|
||||
|
||||
import pandas as pd
|
||||
import shapely # type: ignore
|
||||
from pydantic import BaseModel
|
||||
|
||||
from gisaf.config import conf
|
||||
from gisaf.models.store import Store # noqa: F401
|
||||
|
@ -106,6 +106,12 @@ class TagPlugin:
|
|||
return self.key
|
||||
|
||||
|
||||
class DownloadResponse(BaseModel):
|
||||
file_name: str
|
||||
content_type: str
|
||||
content: str
|
||||
|
||||
|
||||
class DownloadPlugin:
|
||||
"""
|
||||
Base class for all download plugins.
|
||||
|
@ -119,26 +125,26 @@ class DownloadPlugin:
|
|||
self.roles = roles or []
|
||||
self.icon = icon
|
||||
|
||||
async def execute(self, model, item, request):
|
||||
async def execute(self, model, item) -> DownloadResponse:
|
||||
raise NotImplementedError(f'Missing execute in downloader {self.name}')
|
||||
|
||||
|
||||
class DownloadCSVPlugin(DownloadPlugin):
|
||||
async def execute(self, model, item, request):
|
||||
async def execute(self, model, item) -> DownloadResponse:
|
||||
try:
|
||||
values_models = registry.values_for_model[model]
|
||||
except KeyError:
|
||||
raise NotInRegistry
|
||||
for value_model in values_models:
|
||||
df = await value_model.get_as_dataframe(model_id=item.id)
|
||||
df = await value_model.get_as_dataframe(item=item)
|
||||
csv = df.to_csv(date_format='%d/%m/%Y %H:%M', float_format=value_model.float_format)
|
||||
## TODO: implement multiple values for a model (search for values_for_model)
|
||||
break
|
||||
return {
|
||||
'file_name': '{:s}.csv'.format(item.caption),
|
||||
'content_type': 'text/csv',
|
||||
'content': csv
|
||||
}
|
||||
return DownloadResponse(
|
||||
file_name=f'{model.__name__}-id-{item.id}.csv',
|
||||
content_type='text/csv',
|
||||
content=csv
|
||||
)
|
||||
|
||||
|
||||
class PluginManager:
|
||||
|
@ -171,7 +177,7 @@ class PluginManager:
|
|||
self.actions_stores: dict[str, dict[str, list[ActionAction]]] = {}
|
||||
self.executors = defaultdict(list)
|
||||
self.downloaders = defaultdict(list)
|
||||
self.downloaders_stores = defaultdict(list)
|
||||
self.downloaders_stores: dict[str, list[Downloader]] = defaultdict(list)
|
||||
|
||||
registered_models = registry.geom
|
||||
registered_stores = registered_models.keys()
|
||||
|
@ -268,13 +274,13 @@ class PluginManager:
|
|||
logger.warn(f'Downloader plugin {entry_point.name}: skip model {store}'
|
||||
', which is not found in registry')
|
||||
continue
|
||||
self.downloaders_stores[store].append(
|
||||
Downloader(
|
||||
name=downloader.name,
|
||||
roles=downloader.roles,
|
||||
icon=downloader.icon,
|
||||
)
|
||||
_store = Downloader(
|
||||
_plugin=downloader,
|
||||
name=downloader.name,
|
||||
roles=downloader.roles,
|
||||
icon=downloader.icon,
|
||||
)
|
||||
self.downloaders_stores[store].append(_store)
|
||||
logger.info(f'Added downloader plugin {entry_point.name}')
|
||||
|
||||
self.tagsStores = TagsStores(
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue