Fix custom plugin downloaders

Change get_as_dataframe call signature
This commit is contained in:
phil 2024-04-06 13:11:38 +05:30
parent 08c53cf894
commit 52e1d2135b
9 changed files with 156 additions and 105 deletions

107
pdm.lock generated
View file

@ -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]]

View file

@ -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",

View file

@ -1 +1 @@
__version__: str = '2023.4.dev56+g775030d.d20240325'
__version__: str = '2023.4.dev62+g08c53cf.d20240405'

View file

@ -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,
)

View file

@ -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:

View file

@ -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

View file

@ -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)

View file

@ -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):

View file

@ -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(