From dcf938e8cd7cc5d956ec8c6e5ea17b467c3352df Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Thu, 24 Apr 2025 12:40:37 -0700 Subject: [PATCH 01/31] poetry-ize --- Pipfile | 31 -- Pipfile.lock | 1102 ------------------------------------------------ poetry.lock | 866 +++++++++++++++++++++++++++++++++++++ pyproject.toml | 44 ++ 4 files changed, 910 insertions(+), 1133 deletions(-) delete mode 100644 Pipfile delete mode 100644 Pipfile.lock create mode 100644 poetry.lock create mode 100644 pyproject.toml diff --git a/Pipfile b/Pipfile deleted file mode 100644 index 0eb0146..0000000 --- a/Pipfile +++ /dev/null @@ -1,31 +0,0 @@ -[[source]] -url = "https://pypi.python.org/simple" -verify_ssl = true -name = "pypi" - -[[source]] -url = "https://pypi.pacificclimate.org/simple" -verify_ssl = true -name = "pcic" - -[packages] -SQLAlchemy = "<2.0" -alembic = "*" -psycopg2 = "*" -numpy = "*" -netCDF4 = "==1.5.*" -nchelpers = {version = "==5.5.11", index = "pcic"} -python-dateutil = "*" -sqlparse = "*" -pycrs = "*" -modelmeta = {editable = true, path = "." } - -[dev-packages] -pytest = "*" -"testing.postgresql" = "*" -alembic = "*" -alembic-verify = "*" -modelmeta = {editable = true, path = "."} - -[requires] -python_version = "3.8" diff --git a/Pipfile.lock b/Pipfile.lock deleted file mode 100644 index 2c58be3..0000000 --- a/Pipfile.lock +++ /dev/null @@ -1,1102 +0,0 @@ -{ - "_meta": { - "hash": { - "sha256": "bee3dcf0fd7d33b916214e619af847e69fb3bbde79653c6afc5240a8fa6425bf" - }, - "pipfile-spec": 6, - "requires": { - "python_version": "3.8" - }, - "sources": [ - { - "name": "pypi", - "url": "https://pypi.python.org/simple", - "verify_ssl": true - }, - { - "name": "pcic", - "url": "https://pypi.pacificclimate.org/simple", - "verify_ssl": true - } - ] - }, - "default": { - "alembic": { - "hashes": [ - "sha256:3db4ce81a9072e1b5aa44c2d202add24553182672a12daf21608d6f62a8f9cf9", - "sha256:d6c96c2482740592777c400550a523bc7a9aada4e210cae2e733354ddae6f6f8" - ], - "index": "pypi", - "version": "==1.11.3" - }, - "cached-property": { - "hashes": [ - "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130", - "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0" - ], - "version": "==1.5.2" - }, - "cftime": { - "hashes": [ - "sha256:055d5d60a756c6c1857cf84d77655bb707057bb6c4a4fbb104a550e76c40aad9", - "sha256:07fdef2f75a0f0952b0376fa4cd08ef8a1dad3b963976ac07517811d434936b7", - "sha256:0955e1f3e1c09a9e0296b50f135ff9719cb2466f81c8ad4a10ef06fa394de984", - "sha256:29c18601abea0fd160fbe423e05c7a56fe1d38dd250a6b010de499a132d3fe18", - "sha256:2abdac6ca5b8b6102f319122546739dfc42406b816c16f2a98a8f0cd406d3bf0", - "sha256:2ba7909a0cd4adcb16797d8d6ab2767e7ddb980b2bf9dbabfc71b3bdd94f072b", - "sha256:3042048324b4d6a1066c978ec78101effdd84320e8862bfdbf8122d7ad7588ec", - "sha256:455cec3627e6ca8694b0d9201da6581eb4381b58389f1fbcb51a14fa0e2b3d94", - "sha256:56d0242fc4990584b265622622b25bb262a178097711d2d95e53ef52a9d23e7e", - "sha256:8614c00fb8a5046de304fdd86dbd224f99408185d7b245ac6628d0276596e6d2", - "sha256:86fe550b94525c327578a90b2e13418ca5ba6c636d5efe3edec310e631757eea", - "sha256:892d5dc38f8b998c83a2a01f131e63896d020586de473e1878f9e85acc70ad44", - "sha256:8d49d69c64cee2c175478eed84c3a57fce083da4ceebce16440f72be561a8489", - "sha256:93f00f454329c1f2588ebca2650e8edf7607d6189dbdcc81b5f3be2080155cc4", - "sha256:acb294fdb80e33545ae54b4421df35c4e578708a5ffce1c00408b2294e70ecef", - "sha256:aedfb7a783d19d7a30cb41951310f3bfe98f9f21fffc723c8af08a11962b0b17", - "sha256:afb5b38b51b8bc02f1656a9f15c52b0b20a3999adbe1ab9ac57f926e0065b48a", - "sha256:b4d2a1920f0aad663f25700b30621ff64af373499e52b544da1148dd8c09409a", - "sha256:e83db2fdda900eb154a9f79dfb665ac6190781c61d2e18151996de5ee7ffd8a2", - "sha256:eb7f8cd0996640b83020133b5ef6b97fc9216c3129eaeeaca361abdff5d82166", - "sha256:ee70fa069802652cf534de1dd3fc590b7d22d4127447bf96ac9849abcdadadf1" - ], - "markers": "python_version >= '3.7'", - "version": "==1.6.2" - }, - "greenlet": { - "hashes": [ - "sha256:03a8f4f3430c3b3ff8d10a2a86028c660355ab637cee9333d63d66b56f09d52a", - "sha256:0bf60faf0bc2468089bdc5edd10555bab6e85152191df713e2ab1fcc86382b5a", - "sha256:1087300cf9700bbf455b1b97e24db18f2f77b55302a68272c56209d5587c12d1", - "sha256:18a7f18b82b52ee85322d7a7874e676f34ab319b9f8cce5de06067384aa8ff43", - "sha256:18e98fb3de7dba1c0a852731c3070cf022d14f0d68b4c87a19cc1016f3bb8b33", - "sha256:1a819eef4b0e0b96bb0d98d797bef17dc1b4a10e8d7446be32d1da33e095dbb8", - "sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088", - "sha256:2780572ec463d44c1d3ae850239508dbeb9fed38e294c68d19a24d925d9223ca", - "sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343", - "sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645", - "sha256:2dd11f291565a81d71dab10b7033395b7a3a5456e637cf997a6f33ebdf06f8db", - "sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df", - "sha256:32e5b64b148966d9cccc2c8d35a671409e45f195864560829f395a54226408d3", - "sha256:36abbf031e1c0f79dd5d596bfaf8e921c41df2bdf54ee1eed921ce1f52999a86", - "sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2", - "sha256:3a51c9751078733d88e013587b108f1b7a1fb106d402fb390740f002b6f6551a", - "sha256:3c9b12575734155d0c09d6c3e10dbd81665d5c18e1a7c6597df72fd05990c8cf", - "sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7", - "sha256:4b58adb399c4d61d912c4c331984d60eb66565175cdf4a34792cd9600f21b394", - "sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40", - "sha256:5454276c07d27a740c5892f4907c86327b632127dd9abec42ee62e12427ff7e3", - "sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6", - "sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74", - "sha256:703f18f3fda276b9a916f0934d2fb6d989bf0b4fb5a64825260eb9bfd52d78f0", - "sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3", - "sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91", - "sha256:7cafd1208fdbe93b67c7086876f061f660cfddc44f404279c1585bbf3cdc64c5", - "sha256:7efde645ca1cc441d6dc4b48c0f7101e8d86b54c8530141b09fd31cef5149ec9", - "sha256:8512a0c38cfd4e66a858ddd1b17705587900dd760c6003998e9472b77b56d417", - "sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8", - "sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b", - "sha256:910841381caba4f744a44bf81bfd573c94e10b3045ee00de0cbf436fe50673a6", - "sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb", - "sha256:937e9020b514ceedb9c830c55d5c9872abc90f4b5862f89c0887033ae33c6f73", - "sha256:94c817e84245513926588caf1152e3b559ff794d505555211ca041f032abbb6b", - "sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df", - "sha256:9d14b83fab60d5e8abe587d51c75b252bcc21683f24699ada8fb275d7712f5a9", - "sha256:9f35ec95538f50292f6d8f2c9c9f8a3c6540bbfec21c9e5b4b751e0a7c20864f", - "sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0", - "sha256:acd2162a36d3de67ee896c43effcd5ee3de247eb00354db411feb025aa319857", - "sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a", - "sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249", - "sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30", - "sha256:b9ec052b06a0524f0e35bd8790686a1da006bd911dd1ef7d50b77bfbad74e292", - "sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b", - "sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d", - "sha256:be4ed120b52ae4d974aa40215fcdfde9194d63541c7ded40ee12eb4dda57b76b", - "sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c", - "sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca", - "sha256:c9c59a2120b55788e800d82dfa99b9e156ff8f2227f07c5e3012a45a399620b7", - "sha256:cd021c754b162c0fb55ad5d6b9d960db667faad0fa2ff25bb6e1301b0b6e6a75", - "sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae", - "sha256:d4606a527e30548153be1a9f155f4e283d109ffba663a15856089fb55f933e47", - "sha256:d5508f0b173e6aa47273bdc0a0b5ba055b59662ba7c7ee5119528f466585526b", - "sha256:d75209eed723105f9596807495d58d10b3470fa6732dd6756595e89925ce2470", - "sha256:d967650d3f56af314b72df7089d96cda1083a7fc2da05b375d2bc48c82ab3f3c", - "sha256:db1a39669102a1d8d12b57de2bb7e2ec9066a6f2b3da35ae511ff93b01b5d564", - "sha256:dbfcfc0218093a19c252ca8eb9aee3d29cfdcb586df21049b9d777fd32c14fd9", - "sha256:e0f72c9ddb8cd28532185f54cc1453f2c16fb417a08b53a855c4e6a418edd099", - "sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0", - "sha256:ea9872c80c132f4663822dd2a08d404073a5a9b5ba6155bea72fb2a79d1093b5", - "sha256:eff4eb9b7eb3e4d0cae3d28c283dc16d9bed6b193c2e1ace3ed86ce48ea8df19", - "sha256:f82d4d717d8ef19188687aa32b8363e96062911e63ba22a0cff7802a8e58e5f1", - "sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526" - ], - "markers": "python_version >= '3' and platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))", - "version": "==2.0.2" - }, - "importlib-metadata": { - "hashes": [ - "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb", - "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743" - ], - "markers": "python_version < '3.9'", - "version": "==6.8.0" - }, - "importlib-resources": { - "hashes": [ - "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf", - "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4" - ], - "markers": "python_version < '3.9'", - "version": "==6.0.1" - }, - "lxml": { - "hashes": [ - "sha256:05186a0f1346ae12553d66df1cfce6f251589fea3ad3da4f3ef4e34b2d58c6a3", - "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d", - "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a", - "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120", - "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305", - "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287", - "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23", - "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52", - "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f", - "sha256:141f1d1a9b663c679dc524af3ea1773e618907e96075262726c7612c02b149a4", - "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584", - "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f", - "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693", - "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef", - "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5", - "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02", - "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc", - "sha256:2c74524e179f2ad6d2a4f7caf70e2d96639c0954c943ad601a9e146c76408ed7", - "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da", - "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a", - "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40", - "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8", - "sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd", - "sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601", - "sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c", - "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be", - "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2", - "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c", - "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129", - "sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc", - "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2", - "sha256:4f1026bc732b6a7f96369f7bfe1a4f2290fb34dce00d8644bc3036fb351a4ca1", - "sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7", - "sha256:50670615eaf97227d5dc60de2dc99fb134a7130d310d783314e7724bf163f75d", - "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477", - "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d", - "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e", - "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7", - "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2", - "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574", - "sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf", - "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b", - "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98", - "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12", - "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42", - "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35", - "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d", - "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce", - "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d", - "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f", - "sha256:71d66ee82e7417828af6ecd7db817913cb0cf9d4e61aa0ac1fde0583d84358db", - "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4", - "sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694", - "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac", - "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2", - "sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7", - "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96", - "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d", - "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b", - "sha256:9767e79108424fb6c3edf8f81e6730666a50feb01a328f4a016464a5893f835a", - "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13", - "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340", - "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6", - "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458", - "sha256:ae8b9c6deb1e634ba4f1930eb67ef6e6bf6a44b6eb5ad605642b2d6d5ed9ce3c", - "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c", - "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9", - "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432", - "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991", - "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69", - "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf", - "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb", - "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b", - "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833", - "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76", - "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85", - "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e", - "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50", - "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8", - "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4", - "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b", - "sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5", - "sha256:e3cd95e10c2610c360154afdc2f1480aea394f4a4f1ea0a5eacce49640c9b190", - "sha256:e4da8ca0c0c0aea88fd46be8e44bd49716772358d648cce45fe387f7b92374a7", - "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa", - "sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0", - "sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9", - "sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0", - "sha256:fbf521479bcac1e25a663df882c46a641a9bff6b56dc8b0fafaebd2f66fb231b", - "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5", - "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7", - "sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==4.9.3" - }, - "mako": { - "hashes": [ - "sha256:c97c79c018b9165ac9922ae4f32da095ffd3c4e6872b45eded42926deea46818", - "sha256:d60a3903dc3bb01a18ad6a89cdbe2e4eadc69c0bc8ef1e3773ba53d44c3f7a34" - ], - "markers": "python_version >= '3.7'", - "version": "==1.2.4" - }, - "markupsafe": { - "hashes": [ - "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e", - "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e", - "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", - "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", - "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", - "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc", - "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c", - "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0", - "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4", - "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9", - "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", - "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba", - "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d", - "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3", - "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", - "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155", - "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac", - "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52", - "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", - "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8", - "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b", - "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24", - "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea", - "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198", - "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0", - "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee", - "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be", - "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2", - "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707", - "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", - "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58", - "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", - "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636", - "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", - "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad", - "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee", - "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc", - "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2", - "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48", - "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7", - "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e", - "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b", - "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa", - "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5", - "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e", - "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb", - "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", - "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", - "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", - "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2" - ], - "markers": "python_version >= '3.7'", - "version": "==2.1.3" - }, - "modelmeta": { - "editable": true, - "path": "." - }, - "nchelpers": { - "hashes": [ - "sha256:24efde0efc9fe056b66cd661099e1d326dfe50310c0435f5baaa9948096cca55", - "sha256:9084f28b0c677f3e75a4e4effdec2d51be8abb7beefb9a3dbe33a9be75103e6e" - ], - "index": "pcic", - "version": "==5.5.11" - }, - "netcdf4": { - "hashes": [ - "sha256:06f7364086fd3ae097e757d2493dc1fe006e9ae9636a109a1e4c914db05d7e18", - "sha256:0774309a8b684654c0bbd4d55bcccaa399ffa6870b5dc2e35dbe919ec637a51f", - "sha256:0a33a953b60ee30dcb78db174231f7ab61923331af9645f84adff684e9add4e2", - "sha256:0f570b5b4cc0434ef8a2a648fdebfa017de695ea7c836b24ae7b216ede4e3345", - "sha256:1442048c93ac668d61d1675a0b0f3aea3a73efa2969636af0cb95a52d119acec", - "sha256:18e257843fc29846909557a9502a29e37b381ee7760923f9280d3b26d844db8c", - "sha256:225d17f7a487ebdab99640294203b61e39e01c951b4e6a4f578d8251623f5f5a", - "sha256:29426faabdc017e89572ff1d7835dab426aae4c22ad1a12d1877b932e969b6ac", - "sha256:318ef7dd29b365f3921f9b359ba54f62cfe3aa46ab4464f45c43624d15c4bf55", - "sha256:339e534057be0b1998f80faeb8f9851f28b42cee5a6047e1adf12c0e38235437", - "sha256:49a44c7382e5e1da39d8bab5d8e406ad30d46fda9386e85a3e69491e6caaca93", - "sha256:5c883a02c55fd1e5b61ad4f83dd7f11f90b894e14d120ba678d9c33d9e4b3a77", - "sha256:7326afa46fd0c1b50d30db9764a1eefbcff576fcffa8e48bef403094590563b8", - "sha256:7519c1e8ad8d3d72636a0aedb5d79bb90556037a59d83811e2057f09ca272b52", - "sha256:75ecf1ef2c841aace539f3326d101efda7c99f6c3283c48a444370aba48525af", - "sha256:804d312a10e6fb196df16bf0d811624d885a51b7ebb3bc648278faa62ffece26", - "sha256:8b4fac95819b0c17ca5fc1a4e8bb31116b6b808cceca0aa8b475bb50abab1063", - "sha256:916434a13ea317934cf248fb70dd5476c498f1def71041fc7e3fd23882ef2cda", - "sha256:a9ba575047ba1be7cf5f1b712c987ce329b4d092582d92c2e268296a06bfa639", - "sha256:b21af57acca0d70c5401f8f779409ab4e818c505fb81706eea8d9475e1f0bb9b", - "sha256:b2b0f370cda5cc5f46239e0a219bf8d4cf442c7d49dbd1c89abb39e71e266c60", - "sha256:bd35c37342d9051d2b8fb12a9208856cc59201a94c78a742a198c81813cb00a8", - "sha256:bdba6ea34680a4c1b7018a4a7155f6112acd063289923c0c61918707e9f26910", - "sha256:bdd344d8de65849fa200f69941f1b15a2611b11b307161ce2fd8ff42148507e8", - "sha256:ca3d468f4812c0999df86e3f428851fb0c17ac34ce0827115c246b0b690e4e84", - "sha256:cdb54afe51c1b06e900c0df5e8567d713ff7a26bf087116a88a99858345dadc6", - "sha256:d784d6cf5baa90909f385bf60ead91138f13ff7f870467e458fb3650ef71b48d", - "sha256:db02d42f7b9c7d68cec351ea63ef3fc2a1ad5e7e74fc7b570b34ceb8c7645bf2", - "sha256:e118bfccda464a381187b1f9c771bf9581c83c566faab309a8ec3f781668da4e", - "sha256:f5e9e1ca99aca1f6d40054ef42b97cf6d00c59d8a438f580cf9dfc309a8eb870", - "sha256:f86399073b582bccd278006ee0213548e7037395e1119f1af9f4faad38279b1e", - "sha256:f92b92f758dfc903af2a8a287fd68a531f73ffd3e5be72b5ad1eb3f083e7aaa2", - "sha256:fd501ccb28ebae6770112968c750a14feb39cb495d788aa67c28360f7c1f2324" - ], - "index": "pypi", - "version": "==1.5.8" - }, - "numpy": { - "hashes": [ - "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f", - "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61", - "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7", - "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400", - "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef", - "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2", - "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d", - "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc", - "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835", - "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706", - "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5", - "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4", - "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6", - "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463", - "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a", - "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f", - "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e", - "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e", - "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694", - "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8", - "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64", - "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d", - "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc", - "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254", - "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2", - "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1", - "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810", - "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9" - ], - "index": "pypi", - "version": "==1.24.4" - }, - "psycopg2": { - "hashes": [ - "sha256:1a6a2d609bce44f78af4556bea0c62a5e7f05c23e5ea9c599e07678995609084", - "sha256:44d93a0109dfdf22fe399b419bcd7fa589d86895d3931b01fb321d74dadc68f1", - "sha256:8275abf628c6dc7ec834ea63f6f3846bf33518907a2b9b693d41fd063767a866", - "sha256:91e81a8333a0037babfc9fe6d11e997a9d4dac0f38c43074886b0d9dead94fe9", - "sha256:b22ed9c66da2589a664e0f1ca2465c29b75aaab36fa209d4fb916025fb9119e5", - "sha256:b6bd7d9d3a7a63faae6edf365f0ed0e9b0a1aaf1da3ca146e6b043fb3eb5d723", - "sha256:c7949770cafbd2f12cecc97dea410c514368908a103acf519f2a346134caa4d5", - "sha256:d1210fcf99aae6f728812d1d2240afc1dc44b9e6cba526a06fb8134f969957c2", - "sha256:d5c5297e2fbc8068d4255f1e606bfc9291f06f91ec31b2a0d4c536210ac5c0a2", - "sha256:e9b04cbef584310a1ac0f0d55bb623ca3244c87c51187645432e342de9ae81a8", - "sha256:f00cc35bd7119f1fed17b85bd1007855194dde2cbd8de01ab8ebb17487440ad8" - ], - "index": "pypi", - "version": "==2.9.7" - }, - "pycrs": { - "hashes": [ - "sha256:3a8cccd92024d813ab81811857f61cddb6ab2f4a1e784595c8dcd6a3a6fd7779" - ], - "index": "pypi", - "version": "==1.0.2" - }, - "python-dateutil": { - "hashes": [ - "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", - "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" - ], - "index": "pypi", - "version": "==2.8.2" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, - "sqlalchemy": { - "hashes": [ - "sha256:03db81b89fe7ef3857b4a00b63dedd632d6183d4ea5a31c5d8a92e000a41fc71", - "sha256:06ff25cbae30c396c4b7737464f2a7fc37a67b7da409993b182b024cec80aed9", - "sha256:0e8e608983e6f85d0852ca61f97e521b62e67969e6e640fe6c6b575d4db68557", - "sha256:171e04eeb5d1c0d96a544caf982621a1711d078dbc5c96f11d6469169bd003f1", - "sha256:1c890421651b45a681181301b3497e4d57c0d01dc001e10438a40e9a9c25ee77", - "sha256:201de072b818f8ad55c80d18d1a788729cccf9be6d9dc3b9d8613b053cd4836d", - "sha256:24e300c0c2147484a002b175f4e1361f102e82c345bf263242f0449672a4bccf", - "sha256:2e126cf98b7fd38f1e33c64484406b78e937b1a280e078ef558b95bf5b6895f6", - "sha256:36e58f8c4fe43984384e3fbe6341ac99b6b4e083de2fe838f0fdb91cebe9e9cb", - "sha256:37ce517c011560d68f1ffb28af65d7e06f873f191eb3a73af5671e9c3fada08a", - "sha256:45806315aae81a0c202752558f0df52b42d11dd7ba0097bf71e253b4215f34f4", - "sha256:4afbbf5ef41ac18e02c8dc1f86c04b22b7a2125f2a030e25bbb4aff31abb224b", - "sha256:5debe7d49b8acf1f3035317e63d9ec8d5e4d904c6e75a2a9246a119f5f2fdf3d", - "sha256:5fb1ebdfc8373b5a291485757bd6431de8d7ed42c27439f543c81f6c8febd729", - "sha256:647e0b309cb4512b1f1b78471fdaf72921b6fa6e750b9f891e09c6e2f0e5326f", - "sha256:706bfa02157b97c136547c406f263e4c6274a7b061b3eb9742915dd774bbc264", - "sha256:7653ed6817c710d0c95558232aba799307d14ae084cc9b1f4c389157ec50df5c", - "sha256:82b08e82da3756765c2e75f327b9bf6b0f043c9c3925fb95fb51e1567fa4ee87", - "sha256:8923dfdf24d5aa8a3adb59723f54118dd4fe62cf59ed0d0d65d940579c1170a4", - "sha256:95b9df9afd680b7a3b13b38adf6e3a38995da5e162cc7524ef08e3be4e5ed3e1", - "sha256:9c21b172dfb22e0db303ff6419451f0cac891d2e911bb9fbf8003d717f1bcf91", - "sha256:a1878ce508edea4a879015ab5215546c444233881301e97ca16fe251e89f1c55", - "sha256:a63e43bf3f668c11bb0444ce6e809c1227b8f067ca1068898f3008a273f52b09", - "sha256:a7f7b5c07ae5c0cfd24c2db86071fb2a3d947da7bd487e359cc91e67ac1c6d2e", - "sha256:a843e34abfd4c797018fd8d00ffffa99fd5184c421f190b6ca99def4087689bd", - "sha256:a9ab2c507a7a439f13ca4499db6d3f50423d1d65dc9b5ed897e70941d9e135b0", - "sha256:ab73ed1a05ff539afc4a7f8cf371764cdf79768ecb7d2ec691e3ff89abbc541e", - "sha256:b31e67ff419013f99ad6f8fc73ee19ea31585e1e9fe773744c0f3ce58c039c30", - "sha256:b6d0c4b15d65087738a6e22e0ff461b407533ff65a73b818089efc8eb2b3e1de", - "sha256:bbdf16372859b8ed3f4d05f925a984771cd2abd18bd187042f24be4886c2a15f", - "sha256:c14b29d9e1529f99efd550cd04dbb6db6ba5d690abb96d52de2bff4ed518bc95", - "sha256:c40f3470e084d31247aea228aa1c39bbc0904c2b9ccbf5d3cfa2ea2dac06f26d", - "sha256:ccf956da45290df6e809ea12c54c02ace7f8ff4d765d6d3dfb3655ee876ce58d", - "sha256:d26f280b8f0a8f497bc10573849ad6dc62e671d2468826e5c748d04ed9e670d5", - "sha256:ec2268de67f73b43320383947e74700e95c6770d0c68c4e615e9897e46296294", - "sha256:f167c8175ab908ce48bd6550679cc6ea20ae169379e73c7720a28f89e53aa532", - "sha256:f835c050ebaa4e48b18403bed2c0fda986525896efd76c245bdd4db995e51a4c", - "sha256:f8a65990c9c490f4651b5c02abccc9f113a7f56fa482031ac8cb88b70bc8ccaa" - ], - "index": "pypi", - "version": "==1.4.49" - }, - "sqlparse": { - "hashes": [ - "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3", - "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c" - ], - "index": "pypi", - "version": "==0.4.4" - }, - "typing-extensions": { - "hashes": [ - "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", - "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2" - ], - "markers": "python_version >= '3.7'", - "version": "==4.7.1" - }, - "zipp": { - "hashes": [ - "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0", - "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147" - ], - "markers": "python_version >= '3.8'", - "version": "==3.16.2" - } - }, - "develop": { - "alembic": { - "hashes": [ - "sha256:3db4ce81a9072e1b5aa44c2d202add24553182672a12daf21608d6f62a8f9cf9", - "sha256:d6c96c2482740592777c400550a523bc7a9aada4e210cae2e733354ddae6f6f8" - ], - "index": "pypi", - "version": "==1.11.3" - }, - "alembic-verify": { - "hashes": [ - "sha256:763c6013b3a7589dacde107ca44a4f34e5a072e5a9aa0675603e5bf417e6f2c6", - "sha256:cab4ae105d573851dbb30e9771944773da938ffbf687c4780d914dda23b363e5" - ], - "index": "pypi", - "version": "==0.1.4" - }, - "asn1crypto": { - "hashes": [ - "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c", - "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67" - ], - "version": "==1.5.1" - }, - "cached-property": { - "hashes": [ - "sha256:9fa5755838eecbb2d234c3aa390bd80fbd3ac6b6869109bfc1b499f7bd89a130", - "sha256:df4f613cf7ad9a588cc381aaf4a512d26265ecebd5eb9e1ba12f1319eb85a6a0" - ], - "version": "==1.5.2" - }, - "cftime": { - "hashes": [ - "sha256:055d5d60a756c6c1857cf84d77655bb707057bb6c4a4fbb104a550e76c40aad9", - "sha256:07fdef2f75a0f0952b0376fa4cd08ef8a1dad3b963976ac07517811d434936b7", - "sha256:0955e1f3e1c09a9e0296b50f135ff9719cb2466f81c8ad4a10ef06fa394de984", - "sha256:29c18601abea0fd160fbe423e05c7a56fe1d38dd250a6b010de499a132d3fe18", - "sha256:2abdac6ca5b8b6102f319122546739dfc42406b816c16f2a98a8f0cd406d3bf0", - "sha256:2ba7909a0cd4adcb16797d8d6ab2767e7ddb980b2bf9dbabfc71b3bdd94f072b", - "sha256:3042048324b4d6a1066c978ec78101effdd84320e8862bfdbf8122d7ad7588ec", - "sha256:455cec3627e6ca8694b0d9201da6581eb4381b58389f1fbcb51a14fa0e2b3d94", - "sha256:56d0242fc4990584b265622622b25bb262a178097711d2d95e53ef52a9d23e7e", - "sha256:8614c00fb8a5046de304fdd86dbd224f99408185d7b245ac6628d0276596e6d2", - "sha256:86fe550b94525c327578a90b2e13418ca5ba6c636d5efe3edec310e631757eea", - "sha256:892d5dc38f8b998c83a2a01f131e63896d020586de473e1878f9e85acc70ad44", - "sha256:8d49d69c64cee2c175478eed84c3a57fce083da4ceebce16440f72be561a8489", - "sha256:93f00f454329c1f2588ebca2650e8edf7607d6189dbdcc81b5f3be2080155cc4", - "sha256:acb294fdb80e33545ae54b4421df35c4e578708a5ffce1c00408b2294e70ecef", - "sha256:aedfb7a783d19d7a30cb41951310f3bfe98f9f21fffc723c8af08a11962b0b17", - "sha256:afb5b38b51b8bc02f1656a9f15c52b0b20a3999adbe1ab9ac57f926e0065b48a", - "sha256:b4d2a1920f0aad663f25700b30621ff64af373499e52b544da1148dd8c09409a", - "sha256:e83db2fdda900eb154a9f79dfb665ac6190781c61d2e18151996de5ee7ffd8a2", - "sha256:eb7f8cd0996640b83020133b5ef6b97fc9216c3129eaeeaca361abdff5d82166", - "sha256:ee70fa069802652cf534de1dd3fc590b7d22d4127447bf96ac9849abcdadadf1" - ], - "markers": "python_version >= '3.7'", - "version": "==1.6.2" - }, - "exceptiongroup": { - "hashes": [ - "sha256:097acd85d473d75af5bb98e41b61ff7fe35efe6675e4f9370ec6ec5126d160e9", - "sha256:343280667a4585d195ca1cf9cef84a4e178c4b6cf2274caef9859782b567d5e3" - ], - "markers": "python_version < '3.11'", - "version": "==1.1.3" - }, - "greenlet": { - "hashes": [ - "sha256:03a8f4f3430c3b3ff8d10a2a86028c660355ab637cee9333d63d66b56f09d52a", - "sha256:0bf60faf0bc2468089bdc5edd10555bab6e85152191df713e2ab1fcc86382b5a", - "sha256:1087300cf9700bbf455b1b97e24db18f2f77b55302a68272c56209d5587c12d1", - "sha256:18a7f18b82b52ee85322d7a7874e676f34ab319b9f8cce5de06067384aa8ff43", - "sha256:18e98fb3de7dba1c0a852731c3070cf022d14f0d68b4c87a19cc1016f3bb8b33", - "sha256:1a819eef4b0e0b96bb0d98d797bef17dc1b4a10e8d7446be32d1da33e095dbb8", - "sha256:26fbfce90728d82bc9e6c38ea4d038cba20b7faf8a0ca53a9c07b67318d46088", - "sha256:2780572ec463d44c1d3ae850239508dbeb9fed38e294c68d19a24d925d9223ca", - "sha256:283737e0da3f08bd637b5ad058507e578dd462db259f7f6e4c5c365ba4ee9343", - "sha256:2d4686f195e32d36b4d7cf2d166857dbd0ee9f3d20ae349b6bf8afc8485b3645", - "sha256:2dd11f291565a81d71dab10b7033395b7a3a5456e637cf997a6f33ebdf06f8db", - "sha256:30bcf80dda7f15ac77ba5af2b961bdd9dbc77fd4ac6105cee85b0d0a5fcf74df", - "sha256:32e5b64b148966d9cccc2c8d35a671409e45f195864560829f395a54226408d3", - "sha256:36abbf031e1c0f79dd5d596bfaf8e921c41df2bdf54ee1eed921ce1f52999a86", - "sha256:3a06ad5312349fec0ab944664b01d26f8d1f05009566339ac6f63f56589bc1a2", - "sha256:3a51c9751078733d88e013587b108f1b7a1fb106d402fb390740f002b6f6551a", - "sha256:3c9b12575734155d0c09d6c3e10dbd81665d5c18e1a7c6597df72fd05990c8cf", - "sha256:3f6ea9bd35eb450837a3d80e77b517ea5bc56b4647f5502cd28de13675ee12f7", - "sha256:4b58adb399c4d61d912c4c331984d60eb66565175cdf4a34792cd9600f21b394", - "sha256:4d2e11331fc0c02b6e84b0d28ece3a36e0548ee1a1ce9ddde03752d9b79bba40", - "sha256:5454276c07d27a740c5892f4907c86327b632127dd9abec42ee62e12427ff7e3", - "sha256:561091a7be172ab497a3527602d467e2b3fbe75f9e783d8b8ce403fa414f71a6", - "sha256:6c3acb79b0bfd4fe733dff8bc62695283b57949ebcca05ae5c129eb606ff2d74", - "sha256:703f18f3fda276b9a916f0934d2fb6d989bf0b4fb5a64825260eb9bfd52d78f0", - "sha256:7492e2b7bd7c9b9916388d9df23fa49d9b88ac0640db0a5b4ecc2b653bf451e3", - "sha256:76ae285c8104046b3a7f06b42f29c7b73f77683df18c49ab5af7983994c2dd91", - "sha256:7cafd1208fdbe93b67c7086876f061f660cfddc44f404279c1585bbf3cdc64c5", - "sha256:7efde645ca1cc441d6dc4b48c0f7101e8d86b54c8530141b09fd31cef5149ec9", - "sha256:8512a0c38cfd4e66a858ddd1b17705587900dd760c6003998e9472b77b56d417", - "sha256:88d9ab96491d38a5ab7c56dd7a3cc37d83336ecc564e4e8816dbed12e5aaefc8", - "sha256:8eab883b3b2a38cc1e050819ef06a7e6344d4a990d24d45bc6f2cf959045a45b", - "sha256:910841381caba4f744a44bf81bfd573c94e10b3045ee00de0cbf436fe50673a6", - "sha256:9190f09060ea4debddd24665d6804b995a9c122ef5917ab26e1566dcc712ceeb", - "sha256:937e9020b514ceedb9c830c55d5c9872abc90f4b5862f89c0887033ae33c6f73", - "sha256:94c817e84245513926588caf1152e3b559ff794d505555211ca041f032abbb6b", - "sha256:971ce5e14dc5e73715755d0ca2975ac88cfdaefcaab078a284fea6cfabf866df", - "sha256:9d14b83fab60d5e8abe587d51c75b252bcc21683f24699ada8fb275d7712f5a9", - "sha256:9f35ec95538f50292f6d8f2c9c9f8a3c6540bbfec21c9e5b4b751e0a7c20864f", - "sha256:a1846f1b999e78e13837c93c778dcfc3365902cfb8d1bdb7dd73ead37059f0d0", - "sha256:acd2162a36d3de67ee896c43effcd5ee3de247eb00354db411feb025aa319857", - "sha256:b0ef99cdbe2b682b9ccbb964743a6aca37905fda5e0452e5ee239b1654d37f2a", - "sha256:b80f600eddddce72320dbbc8e3784d16bd3fb7b517e82476d8da921f27d4b249", - "sha256:b864ba53912b6c3ab6bcb2beb19f19edd01a6bfcbdfe1f37ddd1778abfe75a30", - "sha256:b9ec052b06a0524f0e35bd8790686a1da006bd911dd1ef7d50b77bfbad74e292", - "sha256:ba2956617f1c42598a308a84c6cf021a90ff3862eddafd20c3333d50f0edb45b", - "sha256:bdfea8c661e80d3c1c99ad7c3ff74e6e87184895bbaca6ee8cc61209f8b9b85d", - "sha256:be4ed120b52ae4d974aa40215fcdfde9194d63541c7ded40ee12eb4dda57b76b", - "sha256:c4302695ad8027363e96311df24ee28978162cdcdd2006476c43970b384a244c", - "sha256:c48f54ef8e05f04d6eff74b8233f6063cb1ed960243eacc474ee73a2ea8573ca", - "sha256:c9c59a2120b55788e800d82dfa99b9e156ff8f2227f07c5e3012a45a399620b7", - "sha256:cd021c754b162c0fb55ad5d6b9d960db667faad0fa2ff25bb6e1301b0b6e6a75", - "sha256:d27ec7509b9c18b6d73f2f5ede2622441de812e7b1a80bbd446cb0633bd3d5ae", - "sha256:d4606a527e30548153be1a9f155f4e283d109ffba663a15856089fb55f933e47", - "sha256:d5508f0b173e6aa47273bdc0a0b5ba055b59662ba7c7ee5119528f466585526b", - "sha256:d75209eed723105f9596807495d58d10b3470fa6732dd6756595e89925ce2470", - "sha256:d967650d3f56af314b72df7089d96cda1083a7fc2da05b375d2bc48c82ab3f3c", - "sha256:db1a39669102a1d8d12b57de2bb7e2ec9066a6f2b3da35ae511ff93b01b5d564", - "sha256:dbfcfc0218093a19c252ca8eb9aee3d29cfdcb586df21049b9d777fd32c14fd9", - "sha256:e0f72c9ddb8cd28532185f54cc1453f2c16fb417a08b53a855c4e6a418edd099", - "sha256:e7c8dc13af7db097bed64a051d2dd49e9f0af495c26995c00a9ee842690d34c0", - "sha256:ea9872c80c132f4663822dd2a08d404073a5a9b5ba6155bea72fb2a79d1093b5", - "sha256:eff4eb9b7eb3e4d0cae3d28c283dc16d9bed6b193c2e1ace3ed86ce48ea8df19", - "sha256:f82d4d717d8ef19188687aa32b8363e96062911e63ba22a0cff7802a8e58e5f1", - "sha256:fc3a569657468b6f3fb60587e48356fe512c1754ca05a564f11366ac9e306526" - ], - "markers": "python_version >= '3' and platform_machine == 'aarch64' or (platform_machine == 'ppc64le' or (platform_machine == 'x86_64' or (platform_machine == 'amd64' or (platform_machine == 'AMD64' or (platform_machine == 'win32' or platform_machine == 'WIN32')))))", - "version": "==2.0.2" - }, - "importlib-metadata": { - "hashes": [ - "sha256:3ebb78df84a805d7698245025b975d9d67053cd94c79245ba4b3eb694abe68bb", - "sha256:dbace7892d8c0c4ac1ad096662232f831d4e64f4c4545bd53016a3e9d4654743" - ], - "markers": "python_version < '3.9'", - "version": "==6.8.0" - }, - "importlib-resources": { - "hashes": [ - "sha256:134832a506243891221b88b4ae1213327eea96ceb4e407a00d790bb0626f45cf", - "sha256:4359457e42708462b9626a04657c6208ad799ceb41e5c58c57ffa0e6a098a5d4" - ], - "markers": "python_version < '3.9'", - "version": "==6.0.1" - }, - "iniconfig": { - "hashes": [ - "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", - "sha256:b6a85871a79d2e3b22d2d1b94ac2824226a63c6b741c88f7ae975f18b6778374" - ], - "markers": "python_version >= '3.7'", - "version": "==2.0.0" - }, - "lxml": { - "hashes": [ - "sha256:05186a0f1346ae12553d66df1cfce6f251589fea3ad3da4f3ef4e34b2d58c6a3", - "sha256:075b731ddd9e7f68ad24c635374211376aa05a281673ede86cbe1d1b3455279d", - "sha256:081d32421db5df44c41b7f08a334a090a545c54ba977e47fd7cc2deece78809a", - "sha256:0a3d3487f07c1d7f150894c238299934a2a074ef590b583103a45002035be120", - "sha256:0bfd0767c5c1de2551a120673b72e5d4b628737cb05414f03c3277bf9bed3305", - "sha256:0c0850c8b02c298d3c7006b23e98249515ac57430e16a166873fc47a5d549287", - "sha256:0e2cb47860da1f7e9a5256254b74ae331687b9672dfa780eed355c4c9c3dbd23", - "sha256:120fa9349a24c7043854c53cae8cec227e1f79195a7493e09e0c12e29f918e52", - "sha256:1247694b26342a7bf47c02e513d32225ededd18045264d40758abeb3c838a51f", - "sha256:141f1d1a9b663c679dc524af3ea1773e618907e96075262726c7612c02b149a4", - "sha256:14e019fd83b831b2e61baed40cab76222139926b1fb5ed0e79225bc0cae14584", - "sha256:1509dd12b773c02acd154582088820893109f6ca27ef7291b003d0e81666109f", - "sha256:17a753023436a18e27dd7769e798ce302963c236bc4114ceee5b25c18c52c693", - "sha256:1e224d5755dba2f4a9498e150c43792392ac9b5380aa1b845f98a1618c94eeef", - "sha256:1f447ea5429b54f9582d4b955f5f1985f278ce5cf169f72eea8afd9502973dd5", - "sha256:23eed6d7b1a3336ad92d8e39d4bfe09073c31bfe502f20ca5116b2a334f8ec02", - "sha256:25f32acefac14ef7bd53e4218fe93b804ef6f6b92ffdb4322bb6d49d94cad2bc", - "sha256:2c74524e179f2ad6d2a4f7caf70e2d96639c0954c943ad601a9e146c76408ed7", - "sha256:303bf1edce6ced16bf67a18a1cf8339d0db79577eec5d9a6d4a80f0fb10aa2da", - "sha256:3331bece23c9ee066e0fb3f96c61322b9e0f54d775fccefff4c38ca488de283a", - "sha256:3e9bdd30efde2b9ccfa9cb5768ba04fe71b018a25ea093379c857c9dad262c40", - "sha256:411007c0d88188d9f621b11d252cce90c4a2d1a49db6c068e3c16422f306eab8", - "sha256:42871176e7896d5d45138f6d28751053c711ed4d48d8e30b498da155af39aebd", - "sha256:46f409a2d60f634fe550f7133ed30ad5321ae2e6630f13657fb9479506b00601", - "sha256:48628bd53a426c9eb9bc066a923acaa0878d1e86129fd5359aee99285f4eed9c", - "sha256:48d6ed886b343d11493129e019da91d4039826794a3e3027321c56d9e71505be", - "sha256:4930be26af26ac545c3dffb662521d4e6268352866956672231887d18f0eaab2", - "sha256:4aec80cde9197340bc353d2768e2a75f5f60bacda2bab72ab1dc499589b3878c", - "sha256:4c28a9144688aef80d6ea666c809b4b0e50010a2aca784c97f5e6bf143d9f129", - "sha256:4d2d1edbca80b510443f51afd8496be95529db04a509bc8faee49c7b0fb6d2cc", - "sha256:4dd9a263e845a72eacb60d12401e37c616438ea2e5442885f65082c276dfb2b2", - "sha256:4f1026bc732b6a7f96369f7bfe1a4f2290fb34dce00d8644bc3036fb351a4ca1", - "sha256:4fb960a632a49f2f089d522f70496640fdf1218f1243889da3822e0a9f5f3ba7", - "sha256:50670615eaf97227d5dc60de2dc99fb134a7130d310d783314e7724bf163f75d", - "sha256:50baa9c1c47efcaef189f31e3d00d697c6d4afda5c3cde0302d063492ff9b477", - "sha256:53ace1c1fd5a74ef662f844a0413446c0629d151055340e9893da958a374f70d", - "sha256:5515edd2a6d1a5a70bfcdee23b42ec33425e405c5b351478ab7dc9347228f96e", - "sha256:56dc1f1ebccc656d1b3ed288f11e27172a01503fc016bcabdcbc0978b19352b7", - "sha256:578695735c5a3f51569810dfebd05dd6f888147a34f0f98d4bb27e92b76e05c2", - "sha256:57aba1bbdf450b726d58b2aea5fe47c7875f5afb2c4a23784ed78f19a0462574", - "sha256:57d6ba0ca2b0c462f339640d22882acc711de224d769edf29962b09f77129cbf", - "sha256:5c245b783db29c4e4fbbbfc9c5a78be496c9fea25517f90606aa1f6b2b3d5f7b", - "sha256:5c31c7462abdf8f2ac0577d9f05279727e698f97ecbb02f17939ea99ae8daa98", - "sha256:64f479d719dc9f4c813ad9bb6b28f8390360660b73b2e4beb4cb0ae7104f1c12", - "sha256:65299ea57d82fb91c7f019300d24050c4ddeb7c5a190e076b5f48a2b43d19c42", - "sha256:6689a3d7fd13dc687e9102a27e98ef33730ac4fe37795d5036d18b4d527abd35", - "sha256:690dafd0b187ed38583a648076865d8c229661ed20e48f2335d68e2cf7dc829d", - "sha256:6fc3c450eaa0b56f815c7b62f2b7fba7266c4779adcf1cece9e6deb1de7305ce", - "sha256:704f61ba8c1283c71b16135caf697557f5ecf3e74d9e453233e4771d68a1f42d", - "sha256:71c52db65e4b56b8ddc5bb89fb2e66c558ed9d1a74a45ceb7dcb20c191c3df2f", - "sha256:71d66ee82e7417828af6ecd7db817913cb0cf9d4e61aa0ac1fde0583d84358db", - "sha256:7d298a1bd60c067ea75d9f684f5f3992c9d6766fadbc0bcedd39750bf344c2f4", - "sha256:8b77946fd508cbf0fccd8e400a7f71d4ac0e1595812e66025bac475a8e811694", - "sha256:8d7e43bd40f65f7d97ad8ef5c9b1778943d02f04febef12def25f7583d19baac", - "sha256:8df133a2ea5e74eef5e8fc6f19b9e085f758768a16e9877a60aec455ed2609b2", - "sha256:8ed74706b26ad100433da4b9d807eae371efaa266ffc3e9191ea436087a9d6a7", - "sha256:92af161ecbdb2883c4593d5ed4815ea71b31fafd7fd05789b23100d081ecac96", - "sha256:97047f0d25cd4bcae81f9ec9dc290ca3e15927c192df17331b53bebe0e3ff96d", - "sha256:9719fe17307a9e814580af1f5c6e05ca593b12fb7e44fe62450a5384dbf61b4b", - "sha256:9767e79108424fb6c3edf8f81e6730666a50feb01a328f4a016464a5893f835a", - "sha256:9a92d3faef50658dd2c5470af249985782bf754c4e18e15afb67d3ab06233f13", - "sha256:9bb6ad405121241e99a86efff22d3ef469024ce22875a7ae045896ad23ba2340", - "sha256:9e28c51fa0ce5674be9f560c6761c1b441631901993f76700b1b30ca6c8378d6", - "sha256:aca086dc5f9ef98c512bac8efea4483eb84abbf926eaeedf7b91479feb092458", - "sha256:ae8b9c6deb1e634ba4f1930eb67ef6e6bf6a44b6eb5ad605642b2d6d5ed9ce3c", - "sha256:b0a545b46b526d418eb91754565ba5b63b1c0b12f9bd2f808c852d9b4b2f9b5c", - "sha256:b4e4bc18382088514ebde9328da057775055940a1f2e18f6ad2d78aa0f3ec5b9", - "sha256:b6420a005548ad52154c8ceab4a1290ff78d757f9e5cbc68f8c77089acd3c432", - "sha256:b86164d2cff4d3aaa1f04a14685cbc072efd0b4f99ca5708b2ad1b9b5988a991", - "sha256:bb3bb49c7a6ad9d981d734ef7c7193bc349ac338776a0360cc671eaee89bcf69", - "sha256:bef4e656f7d98aaa3486d2627e7d2df1157d7e88e7efd43a65aa5dd4714916cf", - "sha256:c0781a98ff5e6586926293e59480b64ddd46282953203c76ae15dbbbf302e8bb", - "sha256:c2006f5c8d28dee289f7020f721354362fa304acbaaf9745751ac4006650254b", - "sha256:c41bfca0bd3532d53d16fd34d20806d5c2b1ace22a2f2e4c0008570bf2c58833", - "sha256:cd47b4a0d41d2afa3e58e5bf1f62069255aa2fd6ff5ee41604418ca925911d76", - "sha256:cdb650fc86227eba20de1a29d4b2c1bfe139dc75a0669270033cb2ea3d391b85", - "sha256:cef2502e7e8a96fe5ad686d60b49e1ab03e438bd9123987994528febd569868e", - "sha256:d27be7405547d1f958b60837dc4c1007da90b8b23f54ba1f8b728c78fdb19d50", - "sha256:d37017287a7adb6ab77e1c5bee9bcf9660f90ff445042b790402a654d2ad81d8", - "sha256:d3ff32724f98fbbbfa9f49d82852b159e9784d6094983d9a8b7f2ddaebb063d4", - "sha256:d73d8ecf8ecf10a3bd007f2192725a34bd62898e8da27eb9d32a58084f93962b", - "sha256:dd708cf4ee4408cf46a48b108fb9427bfa00b9b85812a9262b5c668af2533ea5", - "sha256:e3cd95e10c2610c360154afdc2f1480aea394f4a4f1ea0a5eacce49640c9b190", - "sha256:e4da8ca0c0c0aea88fd46be8e44bd49716772358d648cce45fe387f7b92374a7", - "sha256:eadfbbbfb41b44034a4c757fd5d70baccd43296fb894dba0295606a7cf3124aa", - "sha256:ed667f49b11360951e201453fc3967344d0d0263aa415e1619e85ae7fd17b4e0", - "sha256:f3df3db1d336b9356dd3112eae5f5c2b8b377f3bc826848567f10bfddfee77e9", - "sha256:f6bdac493b949141b733c5345b6ba8f87a226029cbabc7e9e121a413e49441e0", - "sha256:fbf521479bcac1e25a663df882c46a641a9bff6b56dc8b0fafaebd2f66fb231b", - "sha256:fc9b106a1bf918db68619fdcd6d5ad4f972fdd19c01d19bdb6bf63f3589a9ec5", - "sha256:fcdd00edfd0a3001e0181eab3e63bd5c74ad3e67152c84f93f13769a40e073a7", - "sha256:fe4bda6bd4340caa6e5cf95e73f8fea5c4bfc55763dd42f1b50a94c1b4a2fbd4" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3, 3.4'", - "version": "==4.9.3" - }, - "mako": { - "hashes": [ - "sha256:c97c79c018b9165ac9922ae4f32da095ffd3c4e6872b45eded42926deea46818", - "sha256:d60a3903dc3bb01a18ad6a89cdbe2e4eadc69c0bc8ef1e3773ba53d44c3f7a34" - ], - "markers": "python_version >= '3.7'", - "version": "==1.2.4" - }, - "markupsafe": { - "hashes": [ - "sha256:05fb21170423db021895e1ea1e1f3ab3adb85d1c2333cbc2310f2a26bc77272e", - "sha256:0a4e4a1aff6c7ac4cd55792abf96c915634c2b97e3cc1c7129578aa68ebd754e", - "sha256:10bbfe99883db80bdbaff2dcf681dfc6533a614f700da1287707e8a5d78a8431", - "sha256:134da1eca9ec0ae528110ccc9e48041e0828d79f24121a1a146161103c76e686", - "sha256:1577735524cdad32f9f694208aa75e422adba74f1baee7551620e43a3141f559", - "sha256:1b40069d487e7edb2676d3fbdb2b0829ffa2cd63a2ec26c4938b2d34391b4ecc", - "sha256:282c2cb35b5b673bbcadb33a585408104df04f14b2d9b01d4c345a3b92861c2c", - "sha256:2c1b19b3aaacc6e57b7e25710ff571c24d6c3613a45e905b1fde04d691b98ee0", - "sha256:2ef12179d3a291be237280175b542c07a36e7f60718296278d8593d21ca937d4", - "sha256:338ae27d6b8745585f87218a3f23f1512dbf52c26c28e322dbe54bcede54ccb9", - "sha256:3c0fae6c3be832a0a0473ac912810b2877c8cb9d76ca48de1ed31e1c68386575", - "sha256:3fd4abcb888d15a94f32b75d8fd18ee162ca0c064f35b11134be77050296d6ba", - "sha256:42de32b22b6b804f42c5d98be4f7e5e977ecdd9ee9b660fda1a3edf03b11792d", - "sha256:504b320cd4b7eff6f968eddf81127112db685e81f7e36e75f9f84f0df46041c3", - "sha256:525808b8019e36eb524b8c68acdd63a37e75714eac50e988180b169d64480a00", - "sha256:56d9f2ecac662ca1611d183feb03a3fa4406469dafe241673d521dd5ae92a155", - "sha256:5bbe06f8eeafd38e5d0a4894ffec89378b6c6a625ff57e3028921f8ff59318ac", - "sha256:65c1a9bcdadc6c28eecee2c119465aebff8f7a584dd719facdd9e825ec61ab52", - "sha256:68e78619a61ecf91e76aa3e6e8e33fc4894a2bebe93410754bd28fce0a8a4f9f", - "sha256:69c0f17e9f5a7afdf2cc9fb2d1ce6aabdb3bafb7f38017c0b77862bcec2bbad8", - "sha256:6b2b56950d93e41f33b4223ead100ea0fe11f8e6ee5f641eb753ce4b77a7042b", - "sha256:787003c0ddb00500e49a10f2844fac87aa6ce977b90b0feaaf9de23c22508b24", - "sha256:7ef3cb2ebbf91e330e3bb937efada0edd9003683db6b57bb108c4001f37a02ea", - "sha256:8023faf4e01efadfa183e863fefde0046de576c6f14659e8782065bcece22198", - "sha256:8758846a7e80910096950b67071243da3e5a20ed2546e6392603c096778d48e0", - "sha256:8afafd99945ead6e075b973fefa56379c5b5c53fd8937dad92c662da5d8fd5ee", - "sha256:8c41976a29d078bb235fea9b2ecd3da465df42a562910f9022f1a03107bd02be", - "sha256:8e254ae696c88d98da6555f5ace2279cf7cd5b3f52be2b5cf97feafe883b58d2", - "sha256:9402b03f1a1b4dc4c19845e5c749e3ab82d5078d16a2a4c2cd2df62d57bb0707", - "sha256:962f82a3086483f5e5f64dbad880d31038b698494799b097bc59c2edf392fce6", - "sha256:9dcdfd0eaf283af041973bff14a2e143b8bd64e069f4c383416ecd79a81aab58", - "sha256:aa7bd130efab1c280bed0f45501b7c8795f9fdbeb02e965371bbef3523627779", - "sha256:ab4a0df41e7c16a1392727727e7998a467472d0ad65f3ad5e6e765015df08636", - "sha256:ad9e82fb8f09ade1c3e1b996a6337afac2b8b9e365f926f5a61aacc71adc5b3c", - "sha256:af598ed32d6ae86f1b747b82783958b1a4ab8f617b06fe68795c7f026abbdcad", - "sha256:b076b6226fb84157e3f7c971a47ff3a679d837cf338547532ab866c57930dbee", - "sha256:b7ff0f54cb4ff66dd38bebd335a38e2c22c41a8ee45aa608efc890ac3e3931bc", - "sha256:bfce63a9e7834b12b87c64d6b155fdd9b3b96191b6bd334bf37db7ff1fe457f2", - "sha256:c011a4149cfbcf9f03994ec2edffcb8b1dc2d2aede7ca243746df97a5d41ce48", - "sha256:c9c804664ebe8f83a211cace637506669e7890fec1b4195b505c214e50dd4eb7", - "sha256:ca379055a47383d02a5400cb0d110cef0a776fc644cda797db0c5696cfd7e18e", - "sha256:cb0932dc158471523c9637e807d9bfb93e06a95cbf010f1a38b98623b929ef2b", - "sha256:cd0f502fe016460680cd20aaa5a76d241d6f35a1c3350c474bac1273803893fa", - "sha256:ceb01949af7121f9fc39f7d27f91be8546f3fb112c608bc4029aef0bab86a2a5", - "sha256:d080e0a5eb2529460b30190fcfcc4199bd7f827663f858a226a81bc27beaa97e", - "sha256:dd15ff04ffd7e05ffcb7fe79f1b98041b8ea30ae9234aed2a9168b5797c3effb", - "sha256:df0be2b576a7abbf737b1575f048c23fb1d769f267ec4358296f31c2479db8f9", - "sha256:e09031c87a1e51556fdcb46e5bd4f59dfb743061cf93c4d6831bf894f125eb57", - "sha256:e4dd52d80b8c83fdce44e12478ad2e85c64ea965e75d66dbeafb0a3e77308fcc", - "sha256:fec21693218efe39aa7f8599346e90c705afa52c5b31ae019b2e57e8f6542bb2" - ], - "markers": "python_version >= '3.7'", - "version": "==2.1.3" - }, - "modelmeta": { - "editable": true, - "path": "." - }, - "nchelpers": { - "hashes": [ - "sha256:24efde0efc9fe056b66cd661099e1d326dfe50310c0435f5baaa9948096cca55", - "sha256:9084f28b0c677f3e75a4e4effdec2d51be8abb7beefb9a3dbe33a9be75103e6e" - ], - "index": "pcic", - "version": "==5.5.11" - }, - "netcdf4": { - "hashes": [ - "sha256:06f7364086fd3ae097e757d2493dc1fe006e9ae9636a109a1e4c914db05d7e18", - "sha256:0774309a8b684654c0bbd4d55bcccaa399ffa6870b5dc2e35dbe919ec637a51f", - "sha256:0a33a953b60ee30dcb78db174231f7ab61923331af9645f84adff684e9add4e2", - "sha256:0f570b5b4cc0434ef8a2a648fdebfa017de695ea7c836b24ae7b216ede4e3345", - "sha256:1442048c93ac668d61d1675a0b0f3aea3a73efa2969636af0cb95a52d119acec", - "sha256:18e257843fc29846909557a9502a29e37b381ee7760923f9280d3b26d844db8c", - "sha256:225d17f7a487ebdab99640294203b61e39e01c951b4e6a4f578d8251623f5f5a", - "sha256:29426faabdc017e89572ff1d7835dab426aae4c22ad1a12d1877b932e969b6ac", - "sha256:318ef7dd29b365f3921f9b359ba54f62cfe3aa46ab4464f45c43624d15c4bf55", - "sha256:339e534057be0b1998f80faeb8f9851f28b42cee5a6047e1adf12c0e38235437", - "sha256:49a44c7382e5e1da39d8bab5d8e406ad30d46fda9386e85a3e69491e6caaca93", - "sha256:5c883a02c55fd1e5b61ad4f83dd7f11f90b894e14d120ba678d9c33d9e4b3a77", - "sha256:7326afa46fd0c1b50d30db9764a1eefbcff576fcffa8e48bef403094590563b8", - "sha256:7519c1e8ad8d3d72636a0aedb5d79bb90556037a59d83811e2057f09ca272b52", - "sha256:75ecf1ef2c841aace539f3326d101efda7c99f6c3283c48a444370aba48525af", - "sha256:804d312a10e6fb196df16bf0d811624d885a51b7ebb3bc648278faa62ffece26", - "sha256:8b4fac95819b0c17ca5fc1a4e8bb31116b6b808cceca0aa8b475bb50abab1063", - "sha256:916434a13ea317934cf248fb70dd5476c498f1def71041fc7e3fd23882ef2cda", - "sha256:a9ba575047ba1be7cf5f1b712c987ce329b4d092582d92c2e268296a06bfa639", - "sha256:b21af57acca0d70c5401f8f779409ab4e818c505fb81706eea8d9475e1f0bb9b", - "sha256:b2b0f370cda5cc5f46239e0a219bf8d4cf442c7d49dbd1c89abb39e71e266c60", - "sha256:bd35c37342d9051d2b8fb12a9208856cc59201a94c78a742a198c81813cb00a8", - "sha256:bdba6ea34680a4c1b7018a4a7155f6112acd063289923c0c61918707e9f26910", - "sha256:bdd344d8de65849fa200f69941f1b15a2611b11b307161ce2fd8ff42148507e8", - "sha256:ca3d468f4812c0999df86e3f428851fb0c17ac34ce0827115c246b0b690e4e84", - "sha256:cdb54afe51c1b06e900c0df5e8567d713ff7a26bf087116a88a99858345dadc6", - "sha256:d784d6cf5baa90909f385bf60ead91138f13ff7f870467e458fb3650ef71b48d", - "sha256:db02d42f7b9c7d68cec351ea63ef3fc2a1ad5e7e74fc7b570b34ceb8c7645bf2", - "sha256:e118bfccda464a381187b1f9c771bf9581c83c566faab309a8ec3f781668da4e", - "sha256:f5e9e1ca99aca1f6d40054ef42b97cf6d00c59d8a438f580cf9dfc309a8eb870", - "sha256:f86399073b582bccd278006ee0213548e7037395e1119f1af9f4faad38279b1e", - "sha256:f92b92f758dfc903af2a8a287fd68a531f73ffd3e5be72b5ad1eb3f083e7aaa2", - "sha256:fd501ccb28ebae6770112968c750a14feb39cb495d788aa67c28360f7c1f2324" - ], - "index": "pypi", - "version": "==1.5.8" - }, - "numpy": { - "hashes": [ - "sha256:04640dab83f7c6c85abf9cd729c5b65f1ebd0ccf9de90b270cd61935eef0197f", - "sha256:1452241c290f3e2a312c137a9999cdbf63f78864d63c79039bda65ee86943f61", - "sha256:222e40d0e2548690405b0b3c7b21d1169117391c2e82c378467ef9ab4c8f0da7", - "sha256:2541312fbf09977f3b3ad449c4e5f4bb55d0dbf79226d7724211acc905049400", - "sha256:31f13e25b4e304632a4619d0e0777662c2ffea99fcae2029556b17d8ff958aef", - "sha256:4602244f345453db537be5314d3983dbf5834a9701b7723ec28923e2889e0bb2", - "sha256:4979217d7de511a8d57f4b4b5b2b965f707768440c17cb70fbf254c4b225238d", - "sha256:4c21decb6ea94057331e111a5bed9a79d335658c27ce2adb580fb4d54f2ad9bc", - "sha256:6620c0acd41dbcb368610bb2f4d83145674040025e5536954782467100aa8835", - "sha256:692f2e0f55794943c5bfff12b3f56f99af76f902fc47487bdfe97856de51a706", - "sha256:7215847ce88a85ce39baf9e89070cb860c98fdddacbaa6c0da3ffb31b3350bd5", - "sha256:79fc682a374c4a8ed08b331bef9c5f582585d1048fa6d80bc6c35bc384eee9b4", - "sha256:7ffe43c74893dbf38c2b0a1f5428760a1a9c98285553c89e12d70a96a7f3a4d6", - "sha256:80f5e3a4e498641401868df4208b74581206afbee7cf7b8329daae82676d9463", - "sha256:95f7ac6540e95bc440ad77f56e520da5bf877f87dca58bd095288dce8940532a", - "sha256:9667575fb6d13c95f1b36aca12c5ee3356bf001b714fc354eb5465ce1609e62f", - "sha256:a5425b114831d1e77e4b5d812b69d11d962e104095a5b9c3b641a218abcc050e", - "sha256:b4bea75e47d9586d31e892a7401f76e909712a0fd510f58f5337bea9572c571e", - "sha256:b7b1fc9864d7d39e28f41d089bfd6353cb5f27ecd9905348c24187a768c79694", - "sha256:befe2bf740fd8373cf56149a5c23a0f601e82869598d41f8e188a0e9869926f8", - "sha256:c0bfb52d2169d58c1cdb8cc1f16989101639b34c7d3ce60ed70b19c63eba0b64", - "sha256:d11efb4dbecbdf22508d55e48d9c8384db795e1b7b51ea735289ff96613ff74d", - "sha256:dd80e219fd4c71fc3699fc1dadac5dcf4fd882bfc6f7ec53d30fa197b8ee22dc", - "sha256:e2926dac25b313635e4d6cf4dc4e51c8c0ebfed60b801c799ffc4c32bf3d1254", - "sha256:e98f220aa76ca2a977fe435f5b04d7b3470c0a2e6312907b37ba6068f26787f2", - "sha256:ed094d4f0c177b1b8e7aa9cba7d6ceed51c0e569a5318ac0ca9a090680a6a1b1", - "sha256:f136bab9c2cfd8da131132c2cf6cc27331dd6fae65f95f69dcd4ae3c3639c810", - "sha256:f3a86ed21e4f87050382c7bc96571755193c4c1392490744ac73d660e8f564a9" - ], - "index": "pypi", - "version": "==1.24.4" - }, - "packaging": { - "hashes": [ - "sha256:994793af429502c4ea2ebf6bf664629d07c1a9fe974af92966e4b8d2df7edc61", - "sha256:a392980d2b6cffa644431898be54b0045151319d1e7ec34f0cfed48767dd334f" - ], - "markers": "python_version >= '3.7'", - "version": "==23.1" - }, - "pg8000": { - "hashes": [ - "sha256:4700e34a01d16c41c923982ff78930e85bbd819aea875f9bc17044eb756125a9", - "sha256:c04280e66a1ccfb5166db5c164164c2e1b8f62afaedffd211451a5329ae84a29" - ], - "markers": "python_version >= '3.8'", - "version": "==1.30.1" - }, - "pluggy": { - "hashes": [ - "sha256:cf61ae8f126ac6f7c451172cf30e3e43d3ca77615509771b3a984a0730651e12", - "sha256:d89c696a773f8bd377d18e5ecda92b7a3793cbe66c87060a6fb58c7b6e1061f7" - ], - "markers": "python_version >= '3.8'", - "version": "==1.3.0" - }, - "psycopg2": { - "hashes": [ - "sha256:1a6a2d609bce44f78af4556bea0c62a5e7f05c23e5ea9c599e07678995609084", - "sha256:44d93a0109dfdf22fe399b419bcd7fa589d86895d3931b01fb321d74dadc68f1", - "sha256:8275abf628c6dc7ec834ea63f6f3846bf33518907a2b9b693d41fd063767a866", - "sha256:91e81a8333a0037babfc9fe6d11e997a9d4dac0f38c43074886b0d9dead94fe9", - "sha256:b22ed9c66da2589a664e0f1ca2465c29b75aaab36fa209d4fb916025fb9119e5", - "sha256:b6bd7d9d3a7a63faae6edf365f0ed0e9b0a1aaf1da3ca146e6b043fb3eb5d723", - "sha256:c7949770cafbd2f12cecc97dea410c514368908a103acf519f2a346134caa4d5", - "sha256:d1210fcf99aae6f728812d1d2240afc1dc44b9e6cba526a06fb8134f969957c2", - "sha256:d5c5297e2fbc8068d4255f1e606bfc9291f06f91ec31b2a0d4c536210ac5c0a2", - "sha256:e9b04cbef584310a1ac0f0d55bb623ca3244c87c51187645432e342de9ae81a8", - "sha256:f00cc35bd7119f1fed17b85bd1007855194dde2cbd8de01ab8ebb17487440ad8" - ], - "index": "pypi", - "version": "==2.9.7" - }, - "pycrs": { - "hashes": [ - "sha256:3a8cccd92024d813ab81811857f61cddb6ab2f4a1e784595c8dcd6a3a6fd7779" - ], - "index": "pypi", - "version": "==1.0.2" - }, - "pytest": { - "hashes": [ - "sha256:78bf16451a2eb8c7a2ea98e32dc119fd2aa758f1d5d66dbf0a59d69a3969df32", - "sha256:b4bf8c45bd59934ed84001ad51e11b4ee40d40a1229d2c79f9c592b0a3f6bd8a" - ], - "index": "pypi", - "version": "==7.4.0" - }, - "python-dateutil": { - "hashes": [ - "sha256:0123cacc1627ae19ddf3c27a5de5bd67ee4586fbdd6440d9748f8abb483d3e86", - "sha256:961d03dc3453ebbc59dbdea9e4e11c5651520a876d0f4db161e8674aae935da9" - ], - "index": "pypi", - "version": "==2.8.2" - }, - "scramp": { - "hashes": [ - "sha256:b142312df7c2977241d951318b7ee923d6b7a4f75ba0f05b621ece1ed616faa3", - "sha256:b7022a140040f33cf863ab2657917ed05287a807b917950489b89b9f685d59bc" - ], - "markers": "python_version >= '3.7'", - "version": "==1.4.4" - }, - "six": { - "hashes": [ - "sha256:1e61c37477a1626458e36f7b1d82aa5c9b094fa4802892072e49de9c60c4c926", - "sha256:8abb2f1d86890a2dfb989f9a77cfcfd3e47c2a354b01111771326f8aa26e0254" - ], - "markers": "python_version >= '2.7' and python_version not in '3.0, 3.1, 3.2, 3.3'", - "version": "==1.16.0" - }, - "sqlalchemy": { - "hashes": [ - "sha256:03db81b89fe7ef3857b4a00b63dedd632d6183d4ea5a31c5d8a92e000a41fc71", - "sha256:06ff25cbae30c396c4b7737464f2a7fc37a67b7da409993b182b024cec80aed9", - "sha256:0e8e608983e6f85d0852ca61f97e521b62e67969e6e640fe6c6b575d4db68557", - "sha256:171e04eeb5d1c0d96a544caf982621a1711d078dbc5c96f11d6469169bd003f1", - "sha256:1c890421651b45a681181301b3497e4d57c0d01dc001e10438a40e9a9c25ee77", - "sha256:201de072b818f8ad55c80d18d1a788729cccf9be6d9dc3b9d8613b053cd4836d", - "sha256:24e300c0c2147484a002b175f4e1361f102e82c345bf263242f0449672a4bccf", - "sha256:2e126cf98b7fd38f1e33c64484406b78e937b1a280e078ef558b95bf5b6895f6", - "sha256:36e58f8c4fe43984384e3fbe6341ac99b6b4e083de2fe838f0fdb91cebe9e9cb", - "sha256:37ce517c011560d68f1ffb28af65d7e06f873f191eb3a73af5671e9c3fada08a", - "sha256:45806315aae81a0c202752558f0df52b42d11dd7ba0097bf71e253b4215f34f4", - "sha256:4afbbf5ef41ac18e02c8dc1f86c04b22b7a2125f2a030e25bbb4aff31abb224b", - "sha256:5debe7d49b8acf1f3035317e63d9ec8d5e4d904c6e75a2a9246a119f5f2fdf3d", - "sha256:5fb1ebdfc8373b5a291485757bd6431de8d7ed42c27439f543c81f6c8febd729", - "sha256:647e0b309cb4512b1f1b78471fdaf72921b6fa6e750b9f891e09c6e2f0e5326f", - "sha256:706bfa02157b97c136547c406f263e4c6274a7b061b3eb9742915dd774bbc264", - "sha256:7653ed6817c710d0c95558232aba799307d14ae084cc9b1f4c389157ec50df5c", - "sha256:82b08e82da3756765c2e75f327b9bf6b0f043c9c3925fb95fb51e1567fa4ee87", - "sha256:8923dfdf24d5aa8a3adb59723f54118dd4fe62cf59ed0d0d65d940579c1170a4", - "sha256:95b9df9afd680b7a3b13b38adf6e3a38995da5e162cc7524ef08e3be4e5ed3e1", - "sha256:9c21b172dfb22e0db303ff6419451f0cac891d2e911bb9fbf8003d717f1bcf91", - "sha256:a1878ce508edea4a879015ab5215546c444233881301e97ca16fe251e89f1c55", - "sha256:a63e43bf3f668c11bb0444ce6e809c1227b8f067ca1068898f3008a273f52b09", - "sha256:a7f7b5c07ae5c0cfd24c2db86071fb2a3d947da7bd487e359cc91e67ac1c6d2e", - "sha256:a843e34abfd4c797018fd8d00ffffa99fd5184c421f190b6ca99def4087689bd", - "sha256:a9ab2c507a7a439f13ca4499db6d3f50423d1d65dc9b5ed897e70941d9e135b0", - "sha256:ab73ed1a05ff539afc4a7f8cf371764cdf79768ecb7d2ec691e3ff89abbc541e", - "sha256:b31e67ff419013f99ad6f8fc73ee19ea31585e1e9fe773744c0f3ce58c039c30", - "sha256:b6d0c4b15d65087738a6e22e0ff461b407533ff65a73b818089efc8eb2b3e1de", - "sha256:bbdf16372859b8ed3f4d05f925a984771cd2abd18bd187042f24be4886c2a15f", - "sha256:c14b29d9e1529f99efd550cd04dbb6db6ba5d690abb96d52de2bff4ed518bc95", - "sha256:c40f3470e084d31247aea228aa1c39bbc0904c2b9ccbf5d3cfa2ea2dac06f26d", - "sha256:ccf956da45290df6e809ea12c54c02ace7f8ff4d765d6d3dfb3655ee876ce58d", - "sha256:d26f280b8f0a8f497bc10573849ad6dc62e671d2468826e5c748d04ed9e670d5", - "sha256:ec2268de67f73b43320383947e74700e95c6770d0c68c4e615e9897e46296294", - "sha256:f167c8175ab908ce48bd6550679cc6ea20ae169379e73c7720a28f89e53aa532", - "sha256:f835c050ebaa4e48b18403bed2c0fda986525896efd76c245bdd4db995e51a4c", - "sha256:f8a65990c9c490f4651b5c02abccc9f113a7f56fa482031ac8cb88b70bc8ccaa" - ], - "index": "pypi", - "version": "==1.4.49" - }, - "sqlalchemy-diff": { - "hashes": [ - "sha256:2a3d4de3cb7580876789a7da25040ae5b827c7a70ee4e733daef1ab68aad0e72", - "sha256:8b618238de87e0062b025b0ff2cb4f9928ddddb64a5bb50bd407cd06b9543314" - ], - "version": "==0.1.5" - }, - "sqlalchemy-utils": { - "hashes": [ - "sha256:6c96b0768ea3f15c0dc56b363d386138c562752b84f647fb8d31a2223aaab801", - "sha256:a2181bff01eeb84479e38571d2c0718eb52042f9afd8c194d0d02877e84b7d74" - ], - "markers": "python_version >= '3.6'", - "version": "==0.41.1" - }, - "sqlparse": { - "hashes": [ - "sha256:5430a4fe2ac7d0f93e66f1efc6e1338a41884b7ddf2a350cedd20ccc4d9d28f3", - "sha256:d446183e84b8349fa3061f0fe7f06ca94ba65b426946ffebe6e3e8295332420c" - ], - "index": "pypi", - "version": "==0.4.4" - }, - "testing.common.database": { - "hashes": [ - "sha256:965d80b2985315325dc358c3061b174a712f4d4d5bf6a80b58b11f9a1dd86d73", - "sha256:e3ed492bf480a87f271f74c53b262caf5d85c8bc09989a8f534fa2283ec52492" - ], - "version": "==2.0.3" - }, - "testing.postgresql": { - "hashes": [ - "sha256:1b41daeb98dfc8cd4a584bb91e8f5f4ab182993870f95257afe5f1ba6151a598", - "sha256:8e1a69760369a7a8ffe63a66b6d95a5cd82db2fb976e4a8f85ffd24fbfc447d8" - ], - "index": "pypi", - "version": "==1.3.0" - }, - "tomli": { - "hashes": [ - "sha256:939de3e7a6161af0c887ef91b7d41a53e7c5a1ca976325f429cb46ea9bc30ecc", - "sha256:de526c12914f0c550d15924c62d72abc48d6fe7364aa87328337a31007fe8a4f" - ], - "markers": "python_version < '3.11'", - "version": "==2.0.1" - }, - "typing-extensions": { - "hashes": [ - "sha256:440d5dd3af93b060174bf433bccd69b0babc3b15b1a8dca43789fd7f61514b36", - "sha256:b75ddc264f0ba5615db7ba217daeb99701ad295353c45f9e95963337ceeeffb2" - ], - "markers": "python_version >= '3.7'", - "version": "==4.7.1" - }, - "zipp": { - "hashes": [ - "sha256:679e51dd4403591b2d6838a48de3d283f3d188412a9782faadf845f298736ba0", - "sha256:ebc15946aa78bd63458992fc81ec3b6f7b1e92d51c35e6de1c3804e73b799147" - ], - "markers": "python_version >= '3.8'", - "version": "==3.16.2" - } - } -} diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..362e845 --- /dev/null +++ b/poetry.lock @@ -0,0 +1,866 @@ +# This file is automatically @generated by Poetry 2.1.2 and should not be changed by hand. + +[[package]] +name = "alembic" +version = "1.15.2" +description = "A database migration tool for SQLAlchemy." +optional = false +python-versions = ">=3.9" +groups = ["main", "test"] +files = [ + {file = "alembic-1.15.2-py3-none-any.whl", hash = "sha256:2e76bd916d547f6900ec4bb5a90aeac1485d2c92536923d0b138c02b126edc53"}, + {file = "alembic-1.15.2.tar.gz", hash = "sha256:1c72391bbdeffccfe317eefba686cb9a3c078005478885413b95c3b26c57a8a7"}, +] + +[package.dependencies] +Mako = "*" +SQLAlchemy = ">=1.4.0" +typing-extensions = ">=4.12" + +[package.extras] +tz = ["tzdata"] + +[[package]] +name = "alembic-verify" +version = "0.1.4" +description = "A library to verify migrations and models are in sync." +optional = false +python-versions = "*" +groups = ["test"] +files = [ + {file = "alembic-verify-0.1.4.tar.gz", hash = "sha256:cab4ae105d573851dbb30e9771944773da938ffbf687c4780d914dda23b363e5"}, + {file = "alembic_verify-0.1.4-py2-none-any.whl", hash = "sha256:763c6013b3a7589dacde107ca44a4f34e5a072e5a9aa0675603e5bf417e6f2c6"}, +] + +[package.dependencies] +alembic = ">=0.8.3" +six = ">=1.10.0" +sqlalchemy-diff = ">=0.1.3" + +[package.extras] +dev = ["coverage (==4.2)", "flake8 (==3.0.4)", "mock (==2.0.0)", "pylint (==1.5.1)", "pytest (==3.0.3)"] +docs = ["Sphinx (==1.3.1)"] + +[[package]] +name = "asn1crypto" +version = "1.5.1" +description = "Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP" +optional = false +python-versions = "*" +groups = ["test"] +files = [ + {file = "asn1crypto-1.5.1-py2.py3-none-any.whl", hash = "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67"}, + {file = "asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c"}, +] + +[[package]] +name = "cached-property" +version = "2.0.1" +description = "A decorator for caching properties in classes." +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "cached_property-2.0.1-py3-none-any.whl", hash = "sha256:f617d70ab1100b7bcf6e42228f9ddcb78c676ffa167278d9f730d1c2fba69ccb"}, + {file = "cached_property-2.0.1.tar.gz", hash = "sha256:484d617105e3ee0e4f1f58725e72a8ef9e93deee462222dbd51cd91230897641"}, +] + +[[package]] +name = "certifi" +version = "2025.1.31" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +groups = ["main"] +files = [ + {file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"}, + {file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"}, +] + +[[package]] +name = "cftime" +version = "1.6.4.post1" +description = "Time-handling functionality from netcdf4-python" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "cftime-1.6.4.post1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0baa9bc4850929da9f92c25329aa1f651e2d6f23e237504f337ee9e12a769f5d"}, + {file = "cftime-1.6.4.post1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:6bb6b087f4b2513c37670bccd457e2a666ca489c5f2aad6e2c0e94604dc1b5b9"}, + {file = "cftime-1.6.4.post1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d9bdeb9174962c9ca00015190bfd693de6b0ec3ec0b3dbc35c693a4f48efdcc"}, + {file = "cftime-1.6.4.post1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e735cfd544878eb94d0108ff5a093bd1a332dba90f979a31a357756d609a90d5"}, + {file = "cftime-1.6.4.post1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:1dcd1b140bf50da6775c56bd7ca179e84bd258b2f159b53eefd5c514b341f2bf"}, + {file = "cftime-1.6.4.post1-cp310-cp310-win_amd64.whl", hash = "sha256:e60b8f24b20753f7548f410f7510e28b941f336f84bd34e3cfd7874af6e70281"}, + {file = "cftime-1.6.4.post1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:1bf7be0a0afc87628cb8c8483412aac6e48e83877004faa0936afb5bf8a877ba"}, + {file = "cftime-1.6.4.post1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0f64ca83acc4e3029f737bf3a32530ffa1fbf53124f5bee70b47548bc58671a7"}, + {file = "cftime-1.6.4.post1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7ebdfd81726b0cfb8b524309224fa952898dfa177c13d5f6af5b18cefbf497d"}, + {file = "cftime-1.6.4.post1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c9ea0965a4c87739aebd84fe8eed966e5809d10065eeffd35c99c274b6f8da15"}, + {file = "cftime-1.6.4.post1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:800a18aea4e8cb2b206450397cb8a53b154798738af3cdd3c922ce1ca198b0e6"}, + {file = "cftime-1.6.4.post1-cp311-cp311-win_amd64.whl", hash = "sha256:5dcfc872f455db1f12eabe3c3ba98e93757cd60ed3526a53246e966ccde46c8a"}, + {file = "cftime-1.6.4.post1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:a590f73506f4704ba5e154ef55bfbaed5e1b4ac170f3caeb8c58e4f2c619ee4e"}, + {file = "cftime-1.6.4.post1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:933cb10e1af4e362e77f513e3eb92b34a688729ddbf938bbdfa5ac20a7f44ba0"}, + {file = "cftime-1.6.4.post1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cf17a1b36f62e9e73c4c9363dd811e1bbf1170f5ac26d343fb26012ccf482908"}, + {file = "cftime-1.6.4.post1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8e18021f421aa26527bad8688c1acf0c85fa72730beb6efce969c316743294f2"}, + {file = "cftime-1.6.4.post1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5835b9d622f9304d1c23a35603a0f068739f428d902860f25e6e7e5a1b7cd8ea"}, + {file = "cftime-1.6.4.post1-cp312-cp312-win_amd64.whl", hash = "sha256:7f50bf0d1b664924aaee636eb2933746b942417d1f8b82ab6c1f6e8ba0da6885"}, + {file = "cftime-1.6.4.post1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:5c89766ebf088c097832ea618c24ed5075331f0b7bf8e9c2d4144aefbf2f1850"}, + {file = "cftime-1.6.4.post1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:7f27113f7ccd1ca32881fdcb9a4bec806a5f54ae621fc1c374f1171f3ed98ef2"}, + {file = "cftime-1.6.4.post1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da367b23eea7cf4df071c88e014a1600d6c5bbf22e3393a4af409903fa397e28"}, + {file = "cftime-1.6.4.post1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6579c5c83cdf09d73aa94c7bc34925edd93c5f2c7dd28e074f568f7e376271a0"}, + {file = "cftime-1.6.4.post1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:6b731c7133d17b479ca0c3c46a7a04f96197f0a4d753f4c2284c3ff0447279b4"}, + {file = "cftime-1.6.4.post1-cp313-cp313-win_amd64.whl", hash = "sha256:d2a8c223faea7f1248ab469cc0d7795dd46f2a423789038f439fee7190bae259"}, + {file = "cftime-1.6.4.post1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:9df3e2d49e548c62d1939e923800b08d2ab732d3ac8d75b857edd7982c878552"}, + {file = "cftime-1.6.4.post1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:2892b7e7654142d825655f60eb66c3e1af745901890316907071d44cf9a18d8a"}, + {file = "cftime-1.6.4.post1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a4ab54e6c04e68395d454cd4001188fc4ade2fe48035589ed65af80c4527ef08"}, + {file = "cftime-1.6.4.post1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:568b69fc52f406e361db62a4d7a219c6fb0ced138937144c3b3a511648dd6c50"}, + {file = "cftime-1.6.4.post1-cp38-cp38-win_amd64.whl", hash = "sha256:640911d2629f4a8f81f6bc0163a983b6b94f86d1007449b8cbfd926136cda253"}, + {file = "cftime-1.6.4.post1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:44e9f8052600803b55f8cb6bcac2be49405c21efa900ec77a9fb7f692db2f7a6"}, + {file = "cftime-1.6.4.post1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a90b6ef4a3fc65322c212a2c99cec75d1886f1ebaf0ff6189f7b327566762222"}, + {file = "cftime-1.6.4.post1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:652700130dbcca3ae36dbb5b61ff360e62aa09fabcabc42ec521091a14389901"}, + {file = "cftime-1.6.4.post1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:24a7fb6cc541a027dab37fdeb695f8a2b21cd7d200be606f81b5abc38f2391e2"}, + {file = "cftime-1.6.4.post1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:fc2c0abe2dbd147e1b1e6d0f3de19a5ea8b04956acc204830fd8418066090989"}, + {file = "cftime-1.6.4.post1-cp39-cp39-win_amd64.whl", hash = "sha256:0ee2f5af8643aa1b47b7e388763a1a6e0dc05558cd2902cffb9cbcf954397648"}, + {file = "cftime-1.6.4.post1.tar.gz", hash = "sha256:50ac76cc9f10ab7bd46e44a71c51a6927051b499b4407df4f29ab13d741b942f"}, +] + +[package.dependencies] +numpy = [ + {version = ">1.13.3", markers = "python_version < \"3.12.0.rc1\""}, + {version = ">=1.26.0b1", markers = "python_version >= \"3.12.0.rc1\""}, +] + +[[package]] +name = "colorama" +version = "0.4.6" +description = "Cross-platform colored terminal text." +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" +groups = ["test"] +markers = "sys_platform == \"win32\"" +files = [ + {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, + {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, +] + +[[package]] +name = "exceptiongroup" +version = "1.2.2" +description = "Backport of PEP 654 (exception groups)" +optional = false +python-versions = ">=3.7" +groups = ["test"] +markers = "python_version == \"3.10\"" +files = [ + {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, + {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, +] + +[package.extras] +test = ["pytest (>=6)"] + +[[package]] +name = "greenlet" +version = "3.2.1" +description = "Lightweight in-process concurrent programming" +optional = false +python-versions = ">=3.9" +groups = ["main", "test"] +markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")" +files = [ + {file = "greenlet-3.2.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:777c1281aa7c786738683e302db0f55eb4b0077c20f1dc53db8852ffaea0a6b0"}, + {file = "greenlet-3.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3059c6f286b53ea4711745146ffe5a5c5ff801f62f6c56949446e0f6461f8157"}, + {file = "greenlet-3.2.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e1a40a17e2c7348f5eee5d8e1b4fa6a937f0587eba89411885a36a8e1fc29bd2"}, + {file = "greenlet-3.2.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5193135b3a8d0017cb438de0d49e92bf2f6c1c770331d24aa7500866f4db4017"}, + {file = "greenlet-3.2.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:639a94d001fe874675b553f28a9d44faed90f9864dc57ba0afef3f8d76a18b04"}, + {file = "greenlet-3.2.1-cp310-cp310-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:8fe303381e7e909e42fb23e191fc69659910909fdcd056b92f6473f80ef18543"}, + {file = "greenlet-3.2.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:72c9b668454e816b5ece25daac1a42c94d1c116d5401399a11b77ce8d883110c"}, + {file = "greenlet-3.2.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6079ae990bbf944cf66bea64a09dcb56085815630955109ffa98984810d71565"}, + {file = "greenlet-3.2.1-cp310-cp310-win_amd64.whl", hash = "sha256:e63cd2035f49376a23611fbb1643f78f8246e9d4dfd607534ec81b175ce582c2"}, + {file = "greenlet-3.2.1-cp311-cp311-macosx_11_0_universal2.whl", hash = "sha256:aa30066fd6862e1153eaae9b51b449a6356dcdb505169647f69e6ce315b9468b"}, + {file = "greenlet-3.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b0f3a0a67786facf3b907a25db80efe74310f9d63cc30869e49c79ee3fcef7e"}, + {file = "greenlet-3.2.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:64a4d0052de53ab3ad83ba86de5ada6aeea8f099b4e6c9ccce70fb29bc02c6a2"}, + {file = "greenlet-3.2.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:852ef432919830022f71a040ff7ba3f25ceb9fe8f3ab784befd747856ee58530"}, + {file = "greenlet-3.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4818116e75a0dd52cdcf40ca4b419e8ce5cb6669630cb4f13a6c384307c9543f"}, + {file = "greenlet-3.2.1-cp311-cp311-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:9afa05fe6557bce1642d8131f87ae9462e2a8e8c46f7ed7929360616088a3975"}, + {file = "greenlet-3.2.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:5c12f0d17a88664757e81a6e3fc7c2452568cf460a2f8fb44f90536b2614000b"}, + {file = "greenlet-3.2.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:dbb4e1aa2000852937dd8f4357fb73e3911da426df8ca9b8df5db231922da474"}, + {file = "greenlet-3.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:cb5ee928ce5fedf9a4b0ccdc547f7887136c4af6109d8f2fe8e00f90c0db47f5"}, + {file = "greenlet-3.2.1-cp312-cp312-macosx_11_0_universal2.whl", hash = "sha256:0ba2811509a30e5f943be048895a983a8daf0b9aa0ac0ead526dfb5d987d80ea"}, + {file = "greenlet-3.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4245246e72352b150a1588d43ddc8ab5e306bef924c26571aafafa5d1aaae4e8"}, + {file = "greenlet-3.2.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7abc0545d8e880779f0c7ce665a1afc3f72f0ca0d5815e2b006cafc4c1cc5840"}, + {file = "greenlet-3.2.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6dcc6d604a6575c6225ac0da39df9335cc0c6ac50725063fa90f104f3dbdb2c9"}, + {file = "greenlet-3.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2273586879affca2d1f414709bb1f61f0770adcabf9eda8ef48fd90b36f15d12"}, + {file = "greenlet-3.2.1-cp312-cp312-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:ff38c869ed30fff07f1452d9a204ece1ec6d3c0870e0ba6e478ce7c1515acf22"}, + {file = "greenlet-3.2.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:e934591a7a4084fa10ee5ef50eb9d2ac8c4075d5c9cf91128116b5dca49d43b1"}, + {file = "greenlet-3.2.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:063bcf7f8ee28eb91e7f7a8148c65a43b73fbdc0064ab693e024b5a940070145"}, + {file = "greenlet-3.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7132e024ebeeeabbe661cf8878aac5d2e643975c4feae833142592ec2f03263d"}, + {file = "greenlet-3.2.1-cp313-cp313-macosx_11_0_universal2.whl", hash = "sha256:e1967882f0c42eaf42282a87579685c8673c51153b845fde1ee81be720ae27ac"}, + {file = "greenlet-3.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e77ae69032a95640a5fe8c857ec7bee569a0997e809570f4c92048691ce4b437"}, + {file = "greenlet-3.2.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3227c6ec1149d4520bc99edac3b9bc8358d0034825f3ca7572165cb502d8f29a"}, + {file = "greenlet-3.2.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0ddda0197c5b46eedb5628d33dad034c455ae77708c7bf192686e760e26d6a0c"}, + {file = "greenlet-3.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de62b542e5dcf0b6116c310dec17b82bb06ef2ceb696156ff7bf74a7a498d982"}, + {file = "greenlet-3.2.1-cp313-cp313-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:c07a0c01010df42f1f058b3973decc69c4d82e036a951c3deaf89ab114054c07"}, + {file = "greenlet-3.2.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:2530bfb0abcd451ea81068e6d0a1aac6dabf3f4c23c8bd8e2a8f579c2dd60d95"}, + {file = "greenlet-3.2.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:1c472adfca310f849903295c351d297559462067f618944ce2650a1878b84123"}, + {file = "greenlet-3.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:24a496479bc8bd01c39aa6516a43c717b4cee7196573c47b1f8e1011f7c12495"}, + {file = "greenlet-3.2.1-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:175d583f7d5ee57845591fc30d852b75b144eb44b05f38b67966ed6df05c8526"}, + {file = "greenlet-3.2.1-cp313-cp313t-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3ecc9d33ca9428e4536ea53e79d781792cee114d2fa2695b173092bdbd8cd6d5"}, + {file = "greenlet-3.2.1-cp313-cp313t-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3f56382ac4df3860ebed8ed838f268f03ddf4e459b954415534130062b16bc32"}, + {file = "greenlet-3.2.1-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cc45a7189c91c0f89aaf9d69da428ce8301b0fd66c914a499199cfb0c28420fc"}, + {file = "greenlet-3.2.1-cp313-cp313t-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:51a2f49da08cff79ee42eb22f1658a2aed60c72792f0a0a95f5f0ca6d101b1fb"}, + {file = "greenlet-3.2.1-cp313-cp313t-musllinux_1_1_aarch64.whl", hash = "sha256:0c68bbc639359493420282d2f34fa114e992a8724481d700da0b10d10a7611b8"}, + {file = "greenlet-3.2.1-cp313-cp313t-musllinux_1_1_x86_64.whl", hash = "sha256:e775176b5c203a1fa4be19f91da00fd3bff536868b77b237da3f4daa5971ae5d"}, + {file = "greenlet-3.2.1-cp314-cp314-macosx_11_0_universal2.whl", hash = "sha256:d6668caf15f181c1b82fb6406f3911696975cc4c37d782e19cb7ba499e556189"}, + {file = "greenlet-3.2.1-cp39-cp39-macosx_11_0_universal2.whl", hash = "sha256:17964c246d4f6e1327edd95e2008988a8995ae3a7732be2f9fc1efed1f1cdf8c"}, + {file = "greenlet-3.2.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:04b4ec7f65f0e4a1500ac475c9343f6cc022b2363ebfb6e94f416085e40dea15"}, + {file = "greenlet-3.2.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b38d53cf268da963869aa25a6e4cc84c1c69afc1ae3391738b2603d110749d01"}, + {file = "greenlet-3.2.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:05a7490f74e8aabc5f29256765a99577ffde979920a2db1f3676d265a3adba41"}, + {file = "greenlet-3.2.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4339b202ac20a89ccd5bde0663b4d00dc62dd25cb3fb14f7f3034dec1b0d9ece"}, + {file = "greenlet-3.2.1-cp39-cp39-manylinux_2_24_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:1a750f1046994b9e038b45ae237d68153c29a3a783075211fb1414a180c8324b"}, + {file = "greenlet-3.2.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:374ffebaa5fbd10919cd599e5cf8ee18bae70c11f9d61e73db79826c8c93d6f9"}, + {file = "greenlet-3.2.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:8b89e5d44f55372efc6072f59ced5ed1efb7b44213dab5ad7e0caba0232c6545"}, + {file = "greenlet-3.2.1-cp39-cp39-win32.whl", hash = "sha256:b7503d6b8bbdac6bbacf5a8c094f18eab7553481a1830975799042f26c9e101b"}, + {file = "greenlet-3.2.1-cp39-cp39-win_amd64.whl", hash = "sha256:e98328b8b8f160925d6b1c5b1879d8e64f6bd8cf11472b7127d579da575b77d9"}, + {file = "greenlet-3.2.1.tar.gz", hash = "sha256:9f4dd4b4946b14bb3bf038f81e1d2e535b7d94f1b2a59fdba1293cd9c1a0a4d7"}, +] + +[package.extras] +docs = ["Sphinx", "furo"] +test = ["objgraph", "psutil"] + +[[package]] +name = "iniconfig" +version = "2.1.0" +description = "brain-dead simple config-ini parsing" +optional = false +python-versions = ">=3.8" +groups = ["test"] +files = [ + {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, + {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, +] + +[[package]] +name = "mako" +version = "1.3.10" +description = "A super-fast templating language that borrows the best ideas from the existing templating languages." +optional = false +python-versions = ">=3.8" +groups = ["main", "test"] +files = [ + {file = "mako-1.3.10-py3-none-any.whl", hash = "sha256:baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59"}, + {file = "mako-1.3.10.tar.gz", hash = "sha256:99579a6f39583fa7e5630a28c3c1f440e4e97a414b80372649c0ce338da2ea28"}, +] + +[package.dependencies] +MarkupSafe = ">=0.9.2" + +[package.extras] +babel = ["Babel"] +lingua = ["lingua"] +testing = ["pytest"] + +[[package]] +name = "markupsafe" +version = "3.0.2" +description = "Safely add untrusted strings to HTML/XML markup." +optional = false +python-versions = ">=3.9" +groups = ["main", "test"] +files = [ + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:38a9ef736c01fccdd6600705b09dc574584b89bea478200c5fbf112a6b0d5579"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bbcb445fa71794da8f178f0f6d66789a28d7319071af7a496d4d507ed566270d"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:57cb5a3cf367aeb1d316576250f65edec5bb3be939e9247ae594b4bcbc317dfb"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:3809ede931876f5b2ec92eef964286840ed3540dadf803dd570c3b7e13141a3b"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:e07c3764494e3776c602c1e78e298937c3315ccc9043ead7e685b7f2b8d47b3c"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:b424c77b206d63d500bcb69fa55ed8d0e6a3774056bdc4839fc9298a7edca171"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win32.whl", hash = "sha256:fcabf5ff6eea076f859677f5f0b6b5c1a51e70a376b0579e0eadef8db48c6b50"}, + {file = "MarkupSafe-3.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:6af100e168aa82a50e186c82875a5893c5597a0c1ccdb0d8b40240b1f28b969a"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, + {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, + {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:ba9527cdd4c926ed0760bc301f6728ef34d841f405abf9d4f959c478421e4efd"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:f8b3d067f2e40fe93e1ccdd6b2e1d16c43140e76f02fb1319a05cf2b79d99430"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:569511d3b58c8791ab4c2e1285575265991e6d8f8700c7be0e88f86cb0672094"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:15ab75ef81add55874e7ab7055e9c397312385bd9ced94920f2802310c930396"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f3818cb119498c0678015754eba762e0d61e5b52d34c8b13d770f0719f7b1d79"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:cdb82a876c47801bb54a690c5ae105a46b392ac6099881cdfb9f6e95e4014c6a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:cabc348d87e913db6ab4aa100f01b08f481097838bdddf7c7a84b7575b7309ca"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:444dcda765c8a838eaae23112db52f1efaf750daddb2d9ca300bcae1039adc5c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win32.whl", hash = "sha256:bcf3e58998965654fdaff38e58584d8937aa3096ab5354d493c77d1fdd66d7a1"}, + {file = "MarkupSafe-3.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:e6a2a455bd412959b57a172ce6328d2dd1f01cb2135efda2e4576e8a23fa3b0f"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_10_13_universal2.whl", hash = "sha256:b5a6b3ada725cea8a5e634536b1b01c30bcdcd7f9c6fff4151548d5bf6b3a36c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:a904af0a6162c73e3edcb969eeeb53a63ceeb5d8cf642fade7d39e7963a22ddb"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa4e5faecf353ed117801a068ebab7b7e09ffb6e1d5e412dc852e0da018126c"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c0ef13eaeee5b615fb07c9a7dadb38eac06a0608b41570d8ade51c56539e509d"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d16a81a06776313e817c951135cf7340a3e91e8c1ff2fac444cfd75fffa04afe"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:6381026f158fdb7c72a168278597a5e3a5222e83ea18f543112b2662a9b699c5"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:3d79d162e7be8f996986c064d1c7c817f6df3a77fe3d6859f6f9e7be4b8c213a"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:131a3c7689c85f5ad20f9f6fb1b866f402c445b220c19fe4308c0b147ccd2ad9"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win32.whl", hash = "sha256:ba8062ed2cf21c07a9e295d5b8a2a5ce678b913b45fdf68c32d95d6c1291e0b6"}, + {file = "MarkupSafe-3.0.2-cp313-cp313t-win_amd64.whl", hash = "sha256:e444a31f8db13eb18ada366ab3cf45fd4b31e4db1236a4448f68778c1d1a5a2f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:eaa0a10b7f72326f1372a713e73c3f739b524b3af41feb43e4921cb529f5929a"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:48032821bbdf20f5799ff537c7ac3d1fba0ba032cfc06194faffa8cda8b560ff"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1a9d3f5f0901fdec14d8d2f66ef7d035f2157240a433441719ac9a3fba440b13"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:88b49a3b9ff31e19998750c38e030fc7bb937398b1f78cfa599aaef92d693144"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:cfad01eed2c2e0c01fd0ecd2ef42c492f7f93902e39a42fc9ee1692961443a29"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:1225beacc926f536dc82e45f8a4d68502949dc67eea90eab715dea3a21c1b5f0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:3169b1eefae027567d1ce6ee7cae382c57fe26e82775f460f0b2778beaad66c0"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:eb7972a85c54febfb25b5c4b4f3af4dcc731994c7da0d8a0b4a6eb0640e1d178"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win32.whl", hash = "sha256:8c4e8c3ce11e1f92f6536ff07154f9d49677ebaaafc32db9db4620bc11ed480f"}, + {file = "MarkupSafe-3.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:6e296a513ca3d94054c2c881cc913116e90fd030ad1c656b3869762b754f5f8a"}, + {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, +] + +[[package]] +name = "nchelpers" +version = "5.5.11" +description = "Helper classes and methods for Climate and Forecast NetCDFdatasets" +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "nchelpers-5.5.11-py3-none-any.whl", hash = "sha256:24efde0efc9fe056b66cd661099e1d326dfe50310c0435f5baaa9948096cca55"}, + {file = "nchelpers-5.5.11.tar.gz", hash = "sha256:9084f28b0c677f3e75a4e4effdec2d51be8abb7beefb9a3dbe33a9be75103e6e"}, +] + +[package.dependencies] +cached-property = "*" +netCDF4 = "*" +python-dateutil = "*" + +[package.source] +type = "legacy" +url = "https://pypi.pacificclimate.org/simple" +reference = "pcic" + +[[package]] +name = "netcdf4" +version = "1.7.2" +description = "Provides an object-oriented python interface to the netCDF version 4 library" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "netCDF4-1.7.2-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:5e9b485e3bd9294d25ff7dc9addefce42b3d23c1ee7e3627605277d159819392"}, + {file = "netCDF4-1.7.2-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:118b476fd00d7e3ab9aa7771186d547da645ae3b49c0c7bdab866793ebf22f07"}, + {file = "netCDF4-1.7.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:abe5b1837ff209185ecfe50bd71884c866b3ee69691051833e410e57f177e059"}, + {file = "netCDF4-1.7.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:28021c7e886e5bccf9a8ce504c032d1d7f98d86f67495fb7cf2c9564eba04510"}, + {file = "netCDF4-1.7.2-cp310-cp310-win_amd64.whl", hash = "sha256:7460b638e41c8ce4179d082a81cb6456f0ce083d4d959f4d9e87a95cd86f64cb"}, + {file = "netCDF4-1.7.2-cp311-cp311-macosx_12_0_x86_64.whl", hash = "sha256:09d61c2ddb6011afb51e77ea0f25cd0bdc28887fb426ffbbc661d920f20c9749"}, + {file = "netCDF4-1.7.2-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:fd2a16dbddeb8fa7cf48c37bfc1967290332f2862bb82f984eec2007bb120aeb"}, + {file = "netCDF4-1.7.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f54f5d39ffbcf1726a1e6fd90cb5fa74277ecea739a5fa0f424636d71beafe24"}, + {file = "netCDF4-1.7.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:902aa50d70f49d002d896212a171d344c38f7b8ca520837c56c922ac1535c4a3"}, + {file = "netCDF4-1.7.2-cp311-cp311-win_amd64.whl", hash = "sha256:3291f9ad0c98c49a4dd16aefad1a9abd3a1b884171db6c81bdcee94671cfabe3"}, + {file = "netCDF4-1.7.2-cp312-cp312-macosx_12_0_x86_64.whl", hash = "sha256:e73e3baa0b74afc414e53ff5095748fdbec7fb346eda351e567c23f2f0d247f1"}, + {file = "netCDF4-1.7.2-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:a51da09258b31776f474c1d47e484fc7214914cdc59edf4cee789ba632184591"}, + {file = "netCDF4-1.7.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb95b11804fe051897d1f2044b05d82a1847bc2549631cdd2f655dde7de77a9c"}, + {file = "netCDF4-1.7.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f9d8a848373723f41ef662590b4f5e1832227501c9fd4513e8ad8da58c269977"}, + {file = "netCDF4-1.7.2-cp312-cp312-win_amd64.whl", hash = "sha256:568ea369e00b581302d77fc5fd0b8f78e520c7e08d0b5af5219ba51f3f1cd694"}, + {file = "netCDF4-1.7.2-cp313-cp313-macosx_12_0_x86_64.whl", hash = "sha256:205a5f1de3ddb993c7c97fb204a923a22408cc2e5facf08d75a8eb89b3e7e1a8"}, + {file = "netCDF4-1.7.2-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:96653fc75057df196010818367c63ba6d7e9af603df0a7fe43fcdad3fe0e9e56"}, + {file = "netCDF4-1.7.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:30d20e56b9ba2c48884eb89c91b63e6c0612b4927881707e34402719153ef17f"}, + {file = "netCDF4-1.7.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8d6bfd38ba0bde04d56f06c1554714a2ea9dab75811c89450dc3ec57a9d36b80"}, + {file = "netCDF4-1.7.2-cp313-cp313-win_amd64.whl", hash = "sha256:5c5fbee6134ee1246c397e1508e5297d825aa19221fdf3fa8dc9727ad824d7a5"}, + {file = "netCDF4-1.7.2-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:6bf402c2c7c063474576e5cf89af877d0b0cd097d9316d5bc4fcb22b62f12567"}, + {file = "netCDF4-1.7.2-cp38-cp38-macosx_14_0_arm64.whl", hash = "sha256:5bdf3b34e6fd4210e34fdc5d1a669a22c4863d96f8a20a3928366acae7b3cbbb"}, + {file = "netCDF4-1.7.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:657774404b9f78a5e4d26506ac9bfe106e4a37238282a70803cc7ce679c5a6cc"}, + {file = "netCDF4-1.7.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7e896d92f01fbf365e33e2513d5a8c4cfe16ff406aae9b6034e5ba1538c8c7a8"}, + {file = "netCDF4-1.7.2-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:eb87c08d1700fe67c301898cf5ba3a3e1f8f2fbb417fcd0e2ac784846b60b058"}, + {file = "netCDF4-1.7.2-cp39-cp39-macosx_14_0_arm64.whl", hash = "sha256:59b403032774c723ee749d7f2135be311bad7d00d1db284bebfab58b9d5cdb92"}, + {file = "netCDF4-1.7.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:572f71459ef4b30e8554dcc4e1e6f55de515acc82a50968b48fe622244a64548"}, + {file = "netCDF4-1.7.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7f77e72281acc5f331f82271e5f7f014d46f5ca9bcaa5aafe3e46d66cee21320"}, + {file = "netCDF4-1.7.2-cp39-cp39-win_amd64.whl", hash = "sha256:d0fa7a9674fae8ae4877e813173c3ff7a6beee166b8730bdc847f517b282ed31"}, + {file = "netcdf4-1.7.2.tar.gz", hash = "sha256:a4c6375540b19989896136943abb6d44850ff6f1fa7d3f063253b1ad3f8b7fce"}, +] + +[package.dependencies] +certifi = "*" +cftime = "*" +numpy = "*" + +[package.extras] +tests = ["Cython", "packaging", "pytest"] + +[[package]] +name = "numpy" +version = "2.2.5" +description = "Fundamental package for array computing in Python" +optional = false +python-versions = ">=3.10" +groups = ["main"] +files = [ + {file = "numpy-2.2.5-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:1f4a922da1729f4c40932b2af4fe84909c7a6e167e6e99f71838ce3a29f3fe26"}, + {file = "numpy-2.2.5-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:b6f91524d31b34f4a5fee24f5bc16dcd1491b668798b6d85585d836c1e633a6a"}, + {file = "numpy-2.2.5-cp310-cp310-macosx_14_0_arm64.whl", hash = "sha256:19f4718c9012e3baea91a7dba661dcab2451cda2550678dc30d53acb91a7290f"}, + {file = "numpy-2.2.5-cp310-cp310-macosx_14_0_x86_64.whl", hash = "sha256:eb7fd5b184e5d277afa9ec0ad5e4eb562ecff541e7f60e69ee69c8d59e9aeaba"}, + {file = "numpy-2.2.5-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6413d48a9be53e183eb06495d8e3b006ef8f87c324af68241bbe7a39e8ff54c3"}, + {file = "numpy-2.2.5-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:7451f92eddf8503c9b8aa4fe6aa7e87fd51a29c2cfc5f7dbd72efde6c65acf57"}, + {file = "numpy-2.2.5-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:0bcb1d057b7571334139129b7f941588f69ce7c4ed15a9d6162b2ea54ded700c"}, + {file = "numpy-2.2.5-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:36ab5b23915887543441efd0417e6a3baa08634308894316f446027611b53bf1"}, + {file = "numpy-2.2.5-cp310-cp310-win32.whl", hash = "sha256:422cc684f17bc963da5f59a31530b3936f57c95a29743056ef7a7903a5dbdf88"}, + {file = "numpy-2.2.5-cp310-cp310-win_amd64.whl", hash = "sha256:e4f0b035d9d0ed519c813ee23e0a733db81ec37d2e9503afbb6e54ccfdee0fa7"}, + {file = "numpy-2.2.5-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c42365005c7a6c42436a54d28c43fe0e01ca11eb2ac3cefe796c25a5f98e5e9b"}, + {file = "numpy-2.2.5-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:498815b96f67dc347e03b719ef49c772589fb74b8ee9ea2c37feae915ad6ebda"}, + {file = "numpy-2.2.5-cp311-cp311-macosx_14_0_arm64.whl", hash = "sha256:6411f744f7f20081b1b4e7112e0f4c9c5b08f94b9f086e6f0adf3645f85d3a4d"}, + {file = "numpy-2.2.5-cp311-cp311-macosx_14_0_x86_64.whl", hash = "sha256:9de6832228f617c9ef45d948ec1cd8949c482238d68b2477e6f642c33a7b0a54"}, + {file = "numpy-2.2.5-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:369e0d4647c17c9363244f3468f2227d557a74b6781cb62ce57cf3ef5cc7c610"}, + {file = "numpy-2.2.5-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:262d23f383170f99cd9191a7c85b9a50970fe9069b2f8ab5d786eca8a675d60b"}, + {file = "numpy-2.2.5-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:aa70fdbdc3b169d69e8c59e65c07a1c9351ceb438e627f0fdcd471015cd956be"}, + {file = "numpy-2.2.5-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:37e32e985f03c06206582a7323ef926b4e78bdaa6915095ef08070471865b906"}, + {file = "numpy-2.2.5-cp311-cp311-win32.whl", hash = "sha256:f5045039100ed58fa817a6227a356240ea1b9a1bc141018864c306c1a16d4175"}, + {file = "numpy-2.2.5-cp311-cp311-win_amd64.whl", hash = "sha256:b13f04968b46ad705f7c8a80122a42ae8f620536ea38cf4bdd374302926424dd"}, + {file = "numpy-2.2.5-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ee461a4eaab4f165b68780a6a1af95fb23a29932be7569b9fab666c407969051"}, + {file = "numpy-2.2.5-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ec31367fd6a255dc8de4772bd1658c3e926d8e860a0b6e922b615e532d320ddc"}, + {file = "numpy-2.2.5-cp312-cp312-macosx_14_0_arm64.whl", hash = "sha256:47834cde750d3c9f4e52c6ca28a7361859fcaf52695c7dc3cc1a720b8922683e"}, + {file = "numpy-2.2.5-cp312-cp312-macosx_14_0_x86_64.whl", hash = "sha256:2c1a1c6ccce4022383583a6ded7bbcda22fc635eb4eb1e0a053336425ed36dfa"}, + {file = "numpy-2.2.5-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9d75f338f5f79ee23548b03d801d28a505198297534f62416391857ea0479571"}, + {file = "numpy-2.2.5-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3a801fef99668f309b88640e28d261991bfad9617c27beda4a3aec4f217ea073"}, + {file = "numpy-2.2.5-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:abe38cd8381245a7f49967a6010e77dbf3680bd3627c0fe4362dd693b404c7f8"}, + {file = "numpy-2.2.5-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:5a0ac90e46fdb5649ab6369d1ab6104bfe5854ab19b645bf5cda0127a13034ae"}, + {file = "numpy-2.2.5-cp312-cp312-win32.whl", hash = "sha256:0cd48122a6b7eab8f06404805b1bd5856200e3ed6f8a1b9a194f9d9054631beb"}, + {file = "numpy-2.2.5-cp312-cp312-win_amd64.whl", hash = "sha256:ced69262a8278547e63409b2653b372bf4baff0870c57efa76c5703fd6543282"}, + {file = "numpy-2.2.5-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:059b51b658f4414fff78c6d7b1b4e18283ab5fa56d270ff212d5ba0c561846f4"}, + {file = "numpy-2.2.5-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:47f9ed103af0bc63182609044b0490747e03bd20a67e391192dde119bf43d52f"}, + {file = "numpy-2.2.5-cp313-cp313-macosx_14_0_arm64.whl", hash = "sha256:261a1ef047751bb02f29dfe337230b5882b54521ca121fc7f62668133cb119c9"}, + {file = "numpy-2.2.5-cp313-cp313-macosx_14_0_x86_64.whl", hash = "sha256:4520caa3807c1ceb005d125a75e715567806fed67e315cea619d5ec6e75a4191"}, + {file = "numpy-2.2.5-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d14b17b9be5f9c9301f43d2e2a4886a33b53f4e6fdf9ca2f4cc60aeeee76372"}, + {file = "numpy-2.2.5-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2ba321813a00e508d5421104464510cc962a6f791aa2fca1c97b1e65027da80d"}, + {file = "numpy-2.2.5-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:a4cbdef3ddf777423060c6f81b5694bad2dc9675f110c4b2a60dc0181543fac7"}, + {file = "numpy-2.2.5-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:54088a5a147ab71a8e7fdfd8c3601972751ded0739c6b696ad9cb0343e21ab73"}, + {file = "numpy-2.2.5-cp313-cp313-win32.whl", hash = "sha256:c8b82a55ef86a2d8e81b63da85e55f5537d2157165be1cb2ce7cfa57b6aef38b"}, + {file = "numpy-2.2.5-cp313-cp313-win_amd64.whl", hash = "sha256:d8882a829fd779f0f43998e931c466802a77ca1ee0fe25a3abe50278616b1471"}, + {file = "numpy-2.2.5-cp313-cp313t-macosx_10_13_x86_64.whl", hash = "sha256:e8b025c351b9f0e8b5436cf28a07fa4ac0204d67b38f01433ac7f9b870fa38c6"}, + {file = "numpy-2.2.5-cp313-cp313t-macosx_11_0_arm64.whl", hash = "sha256:8dfa94b6a4374e7851bbb6f35e6ded2120b752b063e6acdd3157e4d2bb922eba"}, + {file = "numpy-2.2.5-cp313-cp313t-macosx_14_0_arm64.whl", hash = "sha256:97c8425d4e26437e65e1d189d22dff4a079b747ff9c2788057bfb8114ce1e133"}, + {file = "numpy-2.2.5-cp313-cp313t-macosx_14_0_x86_64.whl", hash = "sha256:352d330048c055ea6db701130abc48a21bec690a8d38f8284e00fab256dc1376"}, + {file = "numpy-2.2.5-cp313-cp313t-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8b4c0773b6ada798f51f0f8e30c054d32304ccc6e9c5d93d46cb26f3d385ab19"}, + {file = "numpy-2.2.5-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:55f09e00d4dccd76b179c0f18a44f041e5332fd0e022886ba1c0bbf3ea4a18d0"}, + {file = "numpy-2.2.5-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:02f226baeefa68f7d579e213d0f3493496397d8f1cff5e2b222af274c86a552a"}, + {file = "numpy-2.2.5-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:c26843fd58f65da9491165072da2cccc372530681de481ef670dcc8e27cfb066"}, + {file = "numpy-2.2.5-cp313-cp313t-win32.whl", hash = "sha256:1a161c2c79ab30fe4501d5a2bbfe8b162490757cf90b7f05be8b80bc02f7bb8e"}, + {file = "numpy-2.2.5-cp313-cp313t-win_amd64.whl", hash = "sha256:d403c84991b5ad291d3809bace5e85f4bbf44a04bdc9a88ed2bb1807b3360bb8"}, + {file = "numpy-2.2.5-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:b4ea7e1cff6784e58fe281ce7e7f05036b3e1c89c6f922a6bfbc0a7e8768adbe"}, + {file = "numpy-2.2.5-pp310-pypy310_pp73-macosx_14_0_x86_64.whl", hash = "sha256:d7543263084a85fbc09c704b515395398d31d6395518446237eac219eab9e55e"}, + {file = "numpy-2.2.5-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0255732338c4fdd00996c0421884ea8a3651eea555c3a56b84892b66f696eb70"}, + {file = "numpy-2.2.5-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:d2e3bdadaba0e040d1e7ab39db73e0afe2c74ae277f5614dad53eadbecbbb169"}, + {file = "numpy-2.2.5.tar.gz", hash = "sha256:a9c0d994680cd991b1cb772e8b297340085466a6fe964bc9d4e80f5e2f43c291"}, +] + +[[package]] +name = "packaging" +version = "25.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +groups = ["test"] +files = [ + {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, + {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, +] + +[[package]] +name = "pg8000" +version = "1.31.2" +description = "PostgreSQL interface library" +optional = false +python-versions = ">=3.8" +groups = ["test"] +files = [ + {file = "pg8000-1.31.2-py3-none-any.whl", hash = "sha256:436c771ede71af4d4c22ba867a30add0bc5c942d7ab27fadbb6934a487ecc8f6"}, + {file = "pg8000-1.31.2.tar.gz", hash = "sha256:1ea46cf09d8eca07fe7eaadefd7951e37bee7fabe675df164f1a572ffb300876"}, +] + +[package.dependencies] +python-dateutil = ">=2.8.2" +scramp = ">=1.4.5" + +[[package]] +name = "pluggy" +version = "1.5.0" +description = "plugin and hook calling mechanisms for python" +optional = false +python-versions = ">=3.8" +groups = ["test"] +files = [ + {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, + {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, +] + +[package.extras] +dev = ["pre-commit", "tox"] +testing = ["pytest", "pytest-benchmark"] + +[[package]] +name = "psycopg2" +version = "2.9.10" +description = "psycopg2 - Python-PostgreSQL Database Adapter" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "psycopg2-2.9.10-cp310-cp310-win32.whl", hash = "sha256:5df2b672140f95adb453af93a7d669d7a7bf0a56bcd26f1502329166f4a61716"}, + {file = "psycopg2-2.9.10-cp310-cp310-win_amd64.whl", hash = "sha256:c6f7b8561225f9e711a9c47087388a97fdc948211c10a4bccbf0ba68ab7b3b5a"}, + {file = "psycopg2-2.9.10-cp311-cp311-win32.whl", hash = "sha256:47c4f9875125344f4c2b870e41b6aad585901318068acd01de93f3677a6522c2"}, + {file = "psycopg2-2.9.10-cp311-cp311-win_amd64.whl", hash = "sha256:0435034157049f6846e95103bd8f5a668788dd913a7c30162ca9503fdf542cb4"}, + {file = "psycopg2-2.9.10-cp312-cp312-win32.whl", hash = "sha256:65a63d7ab0e067e2cdb3cf266de39663203d38d6a8ed97f5ca0cb315c73fe067"}, + {file = "psycopg2-2.9.10-cp312-cp312-win_amd64.whl", hash = "sha256:4a579d6243da40a7b3182e0430493dbd55950c493d8c68f4eec0b302f6bbf20e"}, + {file = "psycopg2-2.9.10-cp313-cp313-win_amd64.whl", hash = "sha256:91fd603a2155da8d0cfcdbf8ab24a2d54bca72795b90d2a3ed2b6da8d979dee2"}, + {file = "psycopg2-2.9.10-cp39-cp39-win32.whl", hash = "sha256:9d5b3b94b79a844a986d029eee38998232451119ad653aea42bb9220a8c5066b"}, + {file = "psycopg2-2.9.10-cp39-cp39-win_amd64.whl", hash = "sha256:88138c8dedcbfa96408023ea2b0c369eda40fe5d75002c0964c78f46f11fa442"}, + {file = "psycopg2-2.9.10.tar.gz", hash = "sha256:12ec0b40b0273f95296233e8750441339298e6a572f7039da5b260e3c8b60e11"}, +] + +[[package]] +name = "pycrs" +version = "1.0.2" +description = "GIS package for reading, writing, and converting between CRS formats." +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "PyCRS-1.0.2.tar.gz", hash = "sha256:3a8cccd92024d813ab81811857f61cddb6ab2f4a1e784595c8dcd6a3a6fd7779"}, +] + +[[package]] +name = "pytest" +version = "8.3.5" +description = "pytest: simple powerful testing with Python" +optional = false +python-versions = ">=3.8" +groups = ["test"] +files = [ + {file = "pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820"}, + {file = "pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"}, +] + +[package.dependencies] +colorama = {version = "*", markers = "sys_platform == \"win32\""} +exceptiongroup = {version = ">=1.0.0rc8", markers = "python_version < \"3.11\""} +iniconfig = "*" +packaging = "*" +pluggy = ">=1.5,<2" +tomli = {version = ">=1", markers = "python_version < \"3.11\""} + +[package.extras] +dev = ["argcomplete", "attrs (>=19.2)", "hypothesis (>=3.56)", "mock", "pygments (>=2.7.2)", "requests", "setuptools", "xmlschema"] + +[[package]] +name = "python-dateutil" +version = "2.9.0.post0" +description = "Extensions to the standard Python datetime module" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main", "test"] +files = [ + {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, + {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, +] + +[package.dependencies] +six = ">=1.5" + +[[package]] +name = "scramp" +version = "1.4.5" +description = "An implementation of the SCRAM protocol." +optional = false +python-versions = ">=3.8" +groups = ["test"] +files = [ + {file = "scramp-1.4.5-py3-none-any.whl", hash = "sha256:50e37c464fc67f37994e35bee4151e3d8f9320e9c204fca83a5d313c121bbbe7"}, + {file = "scramp-1.4.5.tar.gz", hash = "sha256:be3fbe774ca577a7a658117dca014e5d254d158cecae3dd60332dfe33ce6d78e"}, +] + +[package.dependencies] +asn1crypto = ">=1.5.1" + +[[package]] +name = "setuptools" +version = "79.0.1" +description = "Easily download, build, install, upgrade, and uninstall Python packages" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "setuptools-79.0.1-py3-none-any.whl", hash = "sha256:e147c0549f27767ba362f9da434eab9c5dc0045d5304feb602a0af001089fc51"}, + {file = "setuptools-79.0.1.tar.gz", hash = "sha256:128ce7b8f33c3079fd1b067ecbb4051a66e8526e7b65f6cec075dfc650ddfa88"}, +] + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\"", "ruff (>=0.8.0) ; sys_platform != \"cygwin\""] +core = ["importlib_metadata (>=6) ; python_version < \"3.10\"", "jaraco.functools (>=4)", "jaraco.text (>=3.7)", "more_itertools", "more_itertools (>=8.8)", "packaging (>=24.2)", "platformdirs (>=4.2.2)", "tomli (>=2.0.1) ; python_version < \"3.11\"", "wheel (>=0.43.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "pygments-github-lexers (==0.0.5)", "pyproject-hooks (!=1.1)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-favicon", "sphinx-inline-tabs", "sphinx-lint", "sphinx-notfound-page (>=1,<2)", "sphinx-reredirects", "sphinxcontrib-towncrier", "towncrier (<24.7)"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["build[virtualenv] (>=1.0.3)", "filelock (>=3.4.0)", "ini2toml[lite] (>=0.14)", "jaraco.develop (>=7.21) ; python_version >= \"3.9\" and sys_platform != \"cygwin\"", "jaraco.envs (>=2.2)", "jaraco.path (>=3.7.2)", "jaraco.test (>=5.5)", "packaging (>=24.2)", "pip (>=19.1)", "pyproject-hooks (!=1.1)", "pytest (>=6,!=8.1.*)", "pytest-home (>=0.5)", "pytest-perf ; sys_platform != \"cygwin\"", "pytest-subprocess", "pytest-timeout", "pytest-xdist (>=3)", "tomli-w (>=1.0.0)", "virtualenv (>=13.0.0)", "wheel (>=0.44.0)"] +type = ["importlib_metadata (>=7.0.2) ; python_version < \"3.10\"", "jaraco.develop (>=7.21) ; sys_platform != \"cygwin\"", "mypy (==1.14.*)", "pytest-mypy"] + +[[package]] +name = "six" +version = "1.17.0" +description = "Python 2 and 3 compatibility utilities" +optional = false +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" +groups = ["main", "test"] +files = [ + {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, + {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, +] + +[[package]] +name = "sqlalchemy" +version = "2.0.40" +description = "Database Abstraction Library" +optional = false +python-versions = ">=3.7" +groups = ["main", "test"] +files = [ + {file = "SQLAlchemy-2.0.40-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ae9597cab738e7cc823f04a704fb754a9249f0b6695a6aeb63b74055cd417a96"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37a5c21ab099a83d669ebb251fddf8f5cee4d75ea40a5a1653d9c43d60e20867"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bece9527f5a98466d67fb5d34dc560c4da964240d8b09024bb21c1246545e04e"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:8bb131ffd2165fae48162c7bbd0d97c84ab961deea9b8bab16366543deeab625"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:9408fd453d5f8990405cc9def9af46bfbe3183e6110401b407c2d073c3388f47"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-win32.whl", hash = "sha256:00a494ea6f42a44c326477b5bee4e0fc75f6a80c01570a32b57e89cf0fbef85a"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-win_amd64.whl", hash = "sha256:c7b927155112ac858357ccf9d255dd8c044fd9ad2dc6ce4c4149527c901fa4c3"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f1ea21bef99c703f44444ad29c2c1b6bd55d202750b6de8e06a955380f4725d7"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:afe63b208153f3a7a2d1a5b9df452b0673082588933e54e7c8aac457cf35e758"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8aae085ea549a1eddbc9298b113cffb75e514eadbb542133dd2b99b5fb3b6af"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ea9181284754d37db15156eb7be09c86e16e50fbe77610e9e7bee09291771a1"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5434223b795be5c5ef8244e5ac98056e290d3a99bdcc539b916e282b160dda00"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:15d08d5ef1b779af6a0909b97be6c1fd4298057504eb6461be88bd1696cb438e"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-win32.whl", hash = "sha256:cd2f75598ae70bcfca9117d9e51a3b06fe29edd972fdd7fd57cc97b4dbf3b08a"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-win_amd64.whl", hash = "sha256:2cbafc8d39ff1abdfdda96435f38fab141892dc759a2165947d1a8fffa7ef596"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f6bacab7514de6146a1976bc56e1545bee247242fab030b89e5f70336fc0003e"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5654d1ac34e922b6c5711631f2da497d3a7bffd6f9f87ac23b35feea56098011"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35904d63412db21088739510216e9349e335f142ce4a04b69e2528020ee19ed4"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c7a80ed86d6aaacb8160a1caef6680d4ddd03c944d985aecee940d168c411d1"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:519624685a51525ddaa7d8ba8265a1540442a2ec71476f0e75241eb8263d6f51"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2ee5f9999a5b0e9689bed96e60ee53c3384f1a05c2dd8068cc2e8361b0df5b7a"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-win32.whl", hash = "sha256:c0cae71e20e3c02c52f6b9e9722bca70e4a90a466d59477822739dc31ac18b4b"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-win_amd64.whl", hash = "sha256:574aea2c54d8f1dd1699449f332c7d9b71c339e04ae50163a3eb5ce4c4325ee4"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9d3b31d0a1c44b74d3ae27a3de422dfccd2b8f0b75e51ecb2faa2bf65ab1ba0d"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:37f7a0f506cf78c80450ed1e816978643d3969f99c4ac6b01104a6fe95c5490a"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bb933a650323e476a2e4fbef8997a10d0003d4da996aad3fd7873e962fdde4d"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6959738971b4745eea16f818a2cd086fb35081383b078272c35ece2b07012716"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:110179728e442dae85dd39591beb74072ae4ad55a44eda2acc6ec98ead80d5f2"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8040680eaacdce4d635f12c55c714f3d4c7f57da2bc47a01229d115bd319191"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-win32.whl", hash = "sha256:650490653b110905c10adac69408380688cefc1f536a137d0d69aca1069dc1d1"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-win_amd64.whl", hash = "sha256:2be94d75ee06548d2fc591a3513422b873490efb124048f50556369a834853b0"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:915866fd50dd868fdcc18d61d8258db1bf9ed7fbd6dfec960ba43365952f3b01"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a4c5a2905a9ccdc67a8963e24abd2f7afcd4348829412483695c59e0af9a705"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55028d7a3ebdf7ace492fab9895cbc5270153f75442a0472d8516e03159ab364"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cfedff6878b0e0d1d0a50666a817ecd85051d12d56b43d9d425455e608b5ba0"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bb19e30fdae77d357ce92192a3504579abe48a66877f476880238a962e5b96db"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:16d325ea898f74b26ffcd1cf8c593b0beed8714f0317df2bed0d8d1de05a8f26"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-win32.whl", hash = "sha256:a669cbe5be3c63f75bcbee0b266779706f1a54bcb1000f302685b87d1b8c1500"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-win_amd64.whl", hash = "sha256:641ee2e0834812d657862f3a7de95e0048bdcb6c55496f39c6fa3d435f6ac6ad"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:50f5885bbed261fc97e2e66c5156244f9704083a674b8d17f24c72217d29baf5"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cf0e99cdb600eabcd1d65cdba0d3c91418fee21c4aa1d28db47d095b1064a7d8"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe147fcd85aaed53ce90645c91ed5fca0cc88a797314c70dfd9d35925bd5d106"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baf7cee56bd552385c1ee39af360772fbfc2f43be005c78d1140204ad6148438"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4aeb939bcac234b88e2d25d5381655e8353fe06b4e50b1c55ecffe56951d18c2"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c268b5100cfeaa222c40f55e169d484efa1384b44bf9ca415eae6d556f02cb08"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-win32.whl", hash = "sha256:46628ebcec4f23a1584fb52f2abe12ddb00f3bb3b7b337618b80fc1b51177aff"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-win_amd64.whl", hash = "sha256:7e0505719939e52a7b0c65d20e84a6044eb3712bb6f239c6b1db77ba8e173a37"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c884de19528e0fcd9dc34ee94c810581dd6e74aef75437ff17e696c2bfefae3e"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1abb387710283fc5983d8a1209d9696a4eae9db8d7ac94b402981fe2fe2e39ad"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cfa124eda500ba4b0d3afc3e91ea27ed4754e727c7f025f293a22f512bcd4c9"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b6b28d303b9d57c17a5164eb1fd2d5119bb6ff4413d5894e74873280483eeb5"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b5a5bbe29c10c5bfd63893747a1bf6f8049df607638c786252cb9243b86b6706"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f0fda83e113bb0fb27dc003685f32a5dcb99c9c4f41f4fa0838ac35265c23b5c"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-win32.whl", hash = "sha256:957f8d85d5e834397ef78a6109550aeb0d27a53b5032f7a57f2451e1adc37e98"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-win_amd64.whl", hash = "sha256:1ffdf9c91428e59744f8e6f98190516f8e1d05eec90e936eb08b257332c5e870"}, + {file = "sqlalchemy-2.0.40-py3-none-any.whl", hash = "sha256:32587e2e1e359276957e6fe5dad089758bc042a971a8a09ae8ecf7a8fe23d07a"}, + {file = "sqlalchemy-2.0.40.tar.gz", hash = "sha256:d827099289c64589418ebbcaead0145cd19f4e3e8a93919a0100247af245fa00"}, +] + +[package.dependencies] +greenlet = {version = ">=1", markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} +typing-extensions = ">=4.6.0" + +[package.extras] +aiomysql = ["aiomysql (>=0.2.0)", "greenlet (>=1)"] +aioodbc = ["aioodbc", "greenlet (>=1)"] +aiosqlite = ["aiosqlite", "greenlet (>=1)", "typing_extensions (!=3.10.0.1)"] +asyncio = ["greenlet (>=1)"] +asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (>=1)"] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10)"] +mssql = ["pyodbc"] +mssql-pymssql = ["pymssql"] +mssql-pyodbc = ["pyodbc"] +mypy = ["mypy (>=0.910)"] +mysql = ["mysqlclient (>=1.4.0)"] +mysql-connector = ["mysql-connector-python"] +oracle = ["cx_oracle (>=8)"] +oracle-oracledb = ["oracledb (>=1.0.1)"] +postgresql = ["psycopg2 (>=2.7)"] +postgresql-asyncpg = ["asyncpg", "greenlet (>=1)"] +postgresql-pg8000 = ["pg8000 (>=1.29.1)"] +postgresql-psycopg = ["psycopg (>=3.0.7)"] +postgresql-psycopg2binary = ["psycopg2-binary"] +postgresql-psycopg2cffi = ["psycopg2cffi"] +postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] +pymysql = ["pymysql"] +sqlcipher = ["sqlcipher3_binary"] + +[[package]] +name = "sqlalchemy-diff" +version = "0.1.5" +description = "Compare two database schemas using sqlalchemy." +optional = false +python-versions = "*" +groups = ["test"] +files = [ + {file = "sqlalchemy-diff-0.1.5.tar.gz", hash = "sha256:2a3d4de3cb7580876789a7da25040ae5b827c7a70ee4e733daef1ab68aad0e72"}, + {file = "sqlalchemy_diff-0.1.5-py3-none-any.whl", hash = "sha256:8b618238de87e0062b025b0ff2cb4f9928ddddb64a5bb50bd407cd06b9543314"}, +] + +[package.dependencies] +sqlalchemy-utils = ">=0.32.4" + +[package.extras] +dev = ["coverage (==5.5)", "flake8 (==3.8.4)", "mysql-connector-python-rf (==2.2.2)", "pylint (==2.7.2)", "pytest (==6.2.2)"] +docs = ["sphinx (==1.4.1)"] + +[[package]] +name = "sqlalchemy-utils" +version = "0.41.2" +description = "Various utility functions for SQLAlchemy." +optional = false +python-versions = ">=3.7" +groups = ["test"] +files = [ + {file = "SQLAlchemy-Utils-0.41.2.tar.gz", hash = "sha256:bc599c8c3b3319e53ce6c5c3c471120bd325d0071fb6f38a10e924e3d07b9990"}, + {file = "SQLAlchemy_Utils-0.41.2-py3-none-any.whl", hash = "sha256:85cf3842da2bf060760f955f8467b87983fb2e30f1764fd0e24a48307dc8ec6e"}, +] + +[package.dependencies] +SQLAlchemy = ">=1.3" + +[package.extras] +arrow = ["arrow (>=0.3.4)"] +babel = ["Babel (>=1.3)"] +color = ["colour (>=0.0.4)"] +encrypted = ["cryptography (>=0.6)"] +intervals = ["intervals (>=0.7.1)"] +password = ["passlib (>=1.6,<2.0)"] +pendulum = ["pendulum (>=2.0.5)"] +phone = ["phonenumbers (>=5.9.2)"] +test = ["Jinja2 (>=2.3)", "Pygments (>=1.2)", "backports.zoneinfo ; python_version < \"3.9\"", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "isort (>=4.2.2)", "pg8000 (>=1.12.4)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +test-all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3.4)", "backports.zoneinfo ; python_version < \"3.9\"", "colour (>=0.0.4)", "cryptography (>=0.6)", "docutils (>=0.10)", "flake8 (>=2.4.0)", "flexmock (>=0.9.7)", "furl (>=0.4.1)", "intervals (>=0.7.1)", "isort (>=4.2.2)", "passlib (>=1.6,<2.0)", "pendulum (>=2.0.5)", "pg8000 (>=1.12.4)", "phonenumbers (>=5.9.2)", "psycopg (>=3.1.8)", "psycopg2 (>=2.5.1)", "psycopg2cffi (>=2.8.1)", "pymysql", "pyodbc", "pytest (==7.4.4)", "python-dateutil", "python-dateutil (>=2.6)", "pytz (>=2014.2)"] +timezone = ["python-dateutil"] +url = ["furl (>=0.4.1)"] + +[[package]] +name = "testing-common-database" +version = "2.0.3" +description = "utilities for testing.* packages" +optional = false +python-versions = "*" +groups = ["test"] +files = [ + {file = "testing.common.database-2.0.3-py2.py3-none-any.whl", hash = "sha256:e3ed492bf480a87f271f74c53b262caf5d85c8bc09989a8f534fa2283ec52492"}, + {file = "testing.common.database-2.0.3.tar.gz", hash = "sha256:965d80b2985315325dc358c3061b174a712f4d4d5bf6a80b58b11f9a1dd86d73"}, +] + +[package.extras] +testing = ["nose"] + +[[package]] +name = "testing-postgresql" +version = "1.3.0" +description = "automatically setups a postgresql instance in a temporary directory, and destroys it after testing" +optional = false +python-versions = "*" +groups = ["test"] +files = [ + {file = "testing.postgresql-1.3.0-py2.py3-none-any.whl", hash = "sha256:1b41daeb98dfc8cd4a584bb91e8f5f4ab182993870f95257afe5f1ba6151a598"}, + {file = "testing.postgresql-1.3.0.tar.gz", hash = "sha256:8e1a69760369a7a8ffe63a66b6d95a5cd82db2fb976e4a8f85ffd24fbfc447d8"}, +] + +[package.dependencies] +pg8000 = ">=1.10" +"testing.common.database" = "*" + +[package.extras] +testing = ["SQLAlchemy", "nose", "psycopg2"] + +[[package]] +name = "tomli" +version = "2.2.1" +description = "A lil' TOML parser" +optional = false +python-versions = ">=3.8" +groups = ["test"] +markers = "python_version == \"3.10\"" +files = [ + {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, + {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ece47d672db52ac607a3d9599a9d48dcb2f2f735c6c2d1f34130085bb12b112a"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6972ca9c9cc9f0acaa56a8ca1ff51e7af152a9f87fb64623e31d5c83700080ee"}, + {file = "tomli-2.2.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c954d2250168d28797dd4e3ac5cf812a406cd5a92674ee4c8f123c889786aa8e"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:8dd28b3e155b80f4d54beb40a441d366adcfe740969820caf156c019fb5c7ec4"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:e59e304978767a54663af13c07b3d1af22ddee3bb2fb0618ca1593e4f593a106"}, + {file = "tomli-2.2.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:33580bccab0338d00994d7f16f4c4ec25b776af3ffaac1ed74e0b3fc95e885a8"}, + {file = "tomli-2.2.1-cp311-cp311-win32.whl", hash = "sha256:465af0e0875402f1d226519c9904f37254b3045fc5084697cefb9bdde1ff99ff"}, + {file = "tomli-2.2.1-cp311-cp311-win_amd64.whl", hash = "sha256:2d0f2fdd22b02c6d81637a3c95f8cd77f995846af7414c5c4b8d0545afa1bc4b"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4a8f6e44de52d5e6c657c9fe83b562f5f4256d8ebbfe4ff922c495620a7f6cea"}, + {file = "tomli-2.2.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8d57ca8095a641b8237d5b079147646153d22552f1c637fd3ba7f4b0b29167a8"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4e340144ad7ae1533cb897d406382b4b6fede8890a03738ff1683af800d54192"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:db2b95f9de79181805df90bedc5a5ab4c165e6ec3fe99f970d0e302f384ad222"}, + {file = "tomli-2.2.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:40741994320b232529c802f8bc86da4e1aa9f413db394617b9a256ae0f9a7f77"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:400e720fe168c0f8521520190686ef8ef033fb19fc493da09779e592861b78c6"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:02abe224de6ae62c19f090f68da4e27b10af2b93213d36cf44e6e1c5abd19fdd"}, + {file = "tomli-2.2.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:b82ebccc8c8a36f2094e969560a1b836758481f3dc360ce9a3277c65f374285e"}, + {file = "tomli-2.2.1-cp312-cp312-win32.whl", hash = "sha256:889f80ef92701b9dbb224e49ec87c645ce5df3fa2cc548664eb8a25e03127a98"}, + {file = "tomli-2.2.1-cp312-cp312-win_amd64.whl", hash = "sha256:7fc04e92e1d624a4a63c76474610238576942d6b8950a2d7f908a340494e67e4"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f4039b9cbc3048b2416cc57ab3bda989a6fcf9b36cf8937f01a6e731b64f80d7"}, + {file = "tomli-2.2.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:286f0ca2ffeeb5b9bd4fcc8d6c330534323ec51b2f52da063b11c502da16f30c"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a92ef1a44547e894e2a17d24e7557a5e85a9e1d0048b0b5e7541f76c5032cb13"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9316dc65bed1684c9a98ee68759ceaed29d229e985297003e494aa825ebb0281"}, + {file = "tomli-2.2.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e85e99945e688e32d5a35c1ff38ed0b3f41f43fad8df0bdf79f72b2ba7bc5272"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:ac065718db92ca818f8d6141b5f66369833d4a80a9d74435a268c52bdfa73140"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:d920f33822747519673ee656a4b6ac33e382eca9d331c87770faa3eef562aeb2"}, + {file = "tomli-2.2.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:a198f10c4d1b1375d7687bc25294306e551bf1abfa4eace6650070a5c1ae2744"}, + {file = "tomli-2.2.1-cp313-cp313-win32.whl", hash = "sha256:d3f5614314d758649ab2ab3a62d4f2004c825922f9e370b29416484086b264ec"}, + {file = "tomli-2.2.1-cp313-cp313-win_amd64.whl", hash = "sha256:a38aa0308e754b0e3c67e344754dff64999ff9b513e691d0e786265c93583c69"}, + {file = "tomli-2.2.1-py3-none-any.whl", hash = "sha256:cb55c73c5f4408779d0cf3eef9f762b9c9f147a77de7b258bef0a5628adc85cc"}, + {file = "tomli-2.2.1.tar.gz", hash = "sha256:cd45e1dc79c835ce60f7404ec8119f2eb06d38b1deba146f07ced3bbc44505ff"}, +] + +[[package]] +name = "typing-extensions" +version = "4.13.2" +description = "Backported and Experimental Type Hints for Python 3.8+" +optional = false +python-versions = ">=3.8" +groups = ["main", "test"] +files = [ + {file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"}, + {file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"}, +] + +[metadata] +lock-version = "2.1" +python-versions = ">=3.10" +content-hash = "b6784d4221d3ebc34b5bb122e059c6580b69729d54d12eb4d5d2a32c645a5e41" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..c074aad --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,44 @@ +[project] +name = "modelmeta" +version = "0.1.2" +description = "An ORM representation of the model meta database" +authors = [ + {name = "James Hiebert", email = "hiebert@uvic.ca"}, + {name = "Rod Glover", email = "rglover@uvic.ca"}, + {name = "Eric Yvorchuk"}, + {name = "Lee Zeman", email = "lzeman@uvic.ca"}, + {name = "David Bronaugh"} +] +requires-python = ">=3.10" +dependencies = [ + "setuptools (>=79.0.1,<80.0.0)", + "sqlalchemy (>=2.0.40,<3.0.0)", + "nchelpers (>=5.5.11,<6.0.0)", + "pycrs (>=1.0.2,<2.0.0)", + "psycopg2 (>=2.9.10,<3.0.0)", + "alembic (>=1.15.2,<2.0.0)", +] + +[tool.poetry] +packages = [{include = "modelmeta"}] + +[[tool.poetry.source]] +name = "pcic" +url = "https://pypi.pacificclimate.org/simple" +priority = "supplemental" + + +[tool.poetry.group.test.dependencies] +pytest = "^8.3.5" +testing-postgresql = "^1.3.0" +alembic-verify = ">=0.1.4,<0.2.0" +sqlalchemy-diff = ">=0.1.5,<0.2.0" + + + + +[tool.poetry.dependencies] +nchelpers = {source = "pcic"} +[build-system] +requires = ["poetry-core>=2.0.0,<3.0.0"] +build-backend = "poetry.core.masonry.api" From f1279cd8c7318530e76662b92133ea89fb73c270 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Fri, 25 Apr 2025 16:59:39 -0700 Subject: [PATCH 02/31] update select() argument format --- .../12f290b63791_handle_variant_sampling_geometries.py | 6 +++--- mm_cataloguer/index_netcdf.py | 6 +++--- mm_cataloguer/psycopg2_adapters.py | 1 - 3 files changed, 6 insertions(+), 7 deletions(-) diff --git a/alembic/versions/12f290b63791_handle_variant_sampling_geometries.py b/alembic/versions/12f290b63791_handle_variant_sampling_geometries.py index 1589d8c..7c731b5 100644 --- a/alembic/versions/12f290b63791_handle_variant_sampling_geometries.py +++ b/alembic/versions/12f290b63791_handle_variant_sampling_geometries.py @@ -46,7 +46,7 @@ def copy_level_set_id_and_grid_id_to_data_file_variables_gridded(): op.get_bind().execute( dfvs_gridded.insert().from_select( ['id', 'level_set_id', 'grid_id'], - sa.select([dfvs.c.data_file_variable_id, dfvs.c.level_set_id, dfvs.c.grid_id]) + sa.select(dfvs.c.data_file_variable_id, dfvs.c.level_set_id, dfvs.c.grid_id) ) ) @@ -147,10 +147,10 @@ def copy_level_set_id_and_grid_id_from_data_file_variables_gridded(): op.get_bind().execute( dfvs.update().values( level_set_id= - sa.select([dfvs_gridded.c.level_set_id]) + sa.select(dfvs_gridded.c.level_set_id) .where(dfvs_gridded.c.id == dfvs.c.data_file_variable_id), grid_id= - sa.select([dfvs_gridded.c.grid_id]) + sa.select(dfvs_gridded.c.grid_id) .where(dfvs_gridded.c.id == dfvs.c.data_file_variable_id), ) ) diff --git a/mm_cataloguer/index_netcdf.py b/mm_cataloguer/index_netcdf.py index b8c2c8a..7cd230d 100644 --- a/mm_cataloguer/index_netcdf.py +++ b/mm_cataloguer/index_netcdf.py @@ -561,14 +561,14 @@ def insert_spatial_ref_sys(sesh, cf, var_name): .cte(name='max_srid') ) next_srid = ( - select([ + select( case([ (max_srid.c.max_srid >= 990000, max_srid.c.max_srid + 1), ], else_=990000).label('next_srid') - ]) + ) .cte(name='next_srid') ) - id = select([next_srid.c.next_srid]) # Used in two places + id = select(next_srid.c.next_srid) # Used in two places proj4_string = cf.proj4_string(var_name, default=default_proj4) diff --git a/mm_cataloguer/psycopg2_adapters.py b/mm_cataloguer/psycopg2_adapters.py index 84c2d11..a207e18 100644 --- a/mm_cataloguer/psycopg2_adapters.py +++ b/mm_cataloguer/psycopg2_adapters.py @@ -18,7 +18,6 @@ def register(): numpy.uint16, numpy.uint32, numpy.uint64, - numpy.float_, numpy.float16, numpy.float32, numpy.float64, From fdbde53ae8d764e48531ede73f7f00cce11effbd Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Fri, 25 Apr 2025 17:12:49 -0700 Subject: [PATCH 03/31] wrap strings sent to execute() with text() --- .../614911daf883_add_seasonal_to_time_resolution_enum.py | 8 ++++---- alembic/versions/7847aa3c1b39_initial_create.py | 2 +- tests/alembic-migrations/test_migrations.py | 4 ++-- tests/conftest.py | 4 ++-- 4 files changed, 9 insertions(+), 9 deletions(-) diff --git a/alembic/versions/614911daf883_add_seasonal_to_time_resolution_enum.py b/alembic/versions/614911daf883_add_seasonal_to_time_resolution_enum.py index 30aa4d0..3ba6235 100644 --- a/alembic/versions/614911daf883_add_seasonal_to_time_resolution_enum.py +++ b/alembic/versions/614911daf883_add_seasonal_to_time_resolution_enum.py @@ -118,22 +118,22 @@ def swap_and_drop(curr_options, dest_options): # Create a temporary enum type, convert to it and drop the old enum type tmp_type.create(connection, checkfirst=False) - op.execute(''' + op.execute(sa.text(''' ALTER TABLE {table_name} ALTER COLUMN {column_name} TYPE {tmp_type_name} USING {column_name}::text::{tmp_type_name} - '''.format(**alter_args)) + '''.format(**alter_args))) old_type.drop(connection, checkfirst=False) # Create and convert to the new enum type new_type.create(connection, checkfirst=False) - op.execute(''' + op.execute(sa.text(''' ALTER TABLE {table_name} ALTER COLUMN {column_name} TYPE {type_name} USING {column_name}::text::{type_name} - '''.format(**alter_args)) + '''.format(**alter_args))) # Drop the temporary enum type tmp_type.drop(connection, checkfirst=False) diff --git a/alembic/versions/7847aa3c1b39_initial_create.py b/alembic/versions/7847aa3c1b39_initial_create.py index 743a8b7..5436816 100644 --- a/alembic/versions/7847aa3c1b39_initial_create.py +++ b/alembic/versions/7847aa3c1b39_initial_create.py @@ -21,7 +21,7 @@ def upgrade(): # but it proved easier (a.k.a. apparently necessary) for testing to do it # here. Also, it makes eminent sense to remove an external manual step in # setting up a new database. Hence: - op.execute('create extension postgis') + op.execute(sa.text('create extension postgis')) op.create_table('emissions', sa.Column('emission_id', sa.Integer(), nullable=False), diff --git a/tests/alembic-migrations/test_migrations.py b/tests/alembic-migrations/test_migrations.py index bc7c505..84929d7 100644 --- a/tests/alembic-migrations/test_migrations.py +++ b/tests/alembic-migrations/test_migrations.py @@ -3,7 +3,7 @@ import pytest -from sqlalchemy import create_engine, MetaData, Table, select +from sqlalchemy import create_engine, MetaData, Table, select, text from sqlalchemy.orm import sessionmaker from alembic import command @@ -55,7 +55,7 @@ def test_model_and_migration_schemas_are_the_same( """ prepare_schema_from_migrations(uri_left, alembic_config_left) engine = create_engine(uri_right) - engine.execute('create extension postgis') + engine.execute(text('create extension postgis')) prepare_schema_from_models(uri_right, Base) result = compare( diff --git a/tests/conftest.py b/tests/conftest.py index de8f7f2..67ef0de 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -31,7 +31,7 @@ import pytest import testing.postgresql -from sqlalchemy import create_engine +from sqlalchemy import create_engine, text from sqlalchemy.orm import sessionmaker from sqlalchemy.schema import CreateSchema @@ -241,7 +241,7 @@ def ensemble2(): # Database initialization def init_database(engine): - engine.execute("create extension postgis") + engine.execute(text("create extension postgis")) # Session-scoped databases, engines, session factories, and derived sessions From 8b953ec576b8eea972939e0c682cdea2131039f3 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Fri, 25 Apr 2025 17:39:06 -0700 Subject: [PATCH 04/31] change autoload to autoload_with and pass in an engine --- .../12f290b63791_handle_variant_sampling_geometries.py | 10 +++++----- tests/alembic-migrations/test_migrations.py | 10 +++++----- 2 files changed, 10 insertions(+), 10 deletions(-) diff --git a/alembic/versions/12f290b63791_handle_variant_sampling_geometries.py b/alembic/versions/12f290b63791_handle_variant_sampling_geometries.py index 7c731b5..b243b8e 100644 --- a/alembic/versions/12f290b63791_handle_variant_sampling_geometries.py +++ b/alembic/versions/12f290b63791_handle_variant_sampling_geometries.py @@ -33,12 +33,12 @@ def copy_level_set_id_and_grid_id_to_data_file_variables_gridded(): dfvs = sa.Table( 'data_file_variables', sa.MetaData(bind=op.get_bind()), - autoload=True + autoload_with=op.get_bind() ) dfvs_gridded = sa.Table( 'data_file_variables_gridded', sa.MetaData(bind=op.get_bind()), - autoload=True + autoload_with=op.get_bind() ) op.get_bind().execute( dfvs.update().values(geometry_type='gridded') @@ -133,12 +133,12 @@ def copy_level_set_id_and_grid_id_from_data_file_variables_gridded(): dfvs = sa.Table( 'data_file_variables', sa.MetaData(bind=op.get_bind()), - autoload=True + autoload_with=op.get_bind() ) dfvs_gridded = sa.Table( 'data_file_variables_gridded', sa.MetaData(bind=op.get_bind()), - autoload=True + autoload_with=op.get_bind() ) if get_dialect() == 'sqlite': # SQLite doesn't support the (standard) form ``UPDATE ... SET ... FROM ...`` @@ -170,7 +170,7 @@ def delete_dsg_time_series_data_file_variables(): dfvs = sa.Table( 'data_file_variables', sa.MetaData(bind=op.get_bind()), - autoload=True + autoload_with=op.get_bind() ) dfvs.delete().where(dfvs.c.geometry_type == 'dsg_time_series') diff --git a/tests/alembic-migrations/test_migrations.py b/tests/alembic-migrations/test_migrations.py index 84929d7..8d69df7 100644 --- a/tests/alembic-migrations/test_migrations.py +++ b/tests/alembic-migrations/test_migrations.py @@ -90,10 +90,10 @@ def test_12f290b63791_upgrade_data_migration(uri_left, alembic_config_left): # Define minimal set of tables needed to test migration meta_data = MetaData(bind=engine) - variable_aliases = Table('variable_aliases', meta_data, autoload=True) - grids = Table('grids', meta_data, autoload=True) - data_files = Table('data_files', meta_data, autoload=True) - data_file_variables = Table('data_file_variables', meta_data, autoload=True) + variable_aliases = Table('variable_aliases', meta_data, autoload_with=engine) + grids = Table('grids', meta_data, autoload_with=engine) + data_files = Table('data_files', meta_data, autoload_with=engine) + data_file_variables = Table('data_file_variables', meta_data, autoload_with=engine) # Insert minimal data needed to test migration: Several instances of each of # variable_aliases, grids, data_files, associated to a data_file_variables. @@ -227,7 +227,7 @@ def test_12f290b63791_downgrade_data_migration(uri_left, alembic_config_left): # Define minimal set of tables needed to test migration meta_data = MetaData(bind=engine) - data_file_variables = Table('data_file_variables', meta_data, autoload=True) + data_file_variables = Table('data_file_variables', meta_data, autoload_with=engine) # Check data results of migration. results = list(engine.execute( From dda4538aff0a4715048a9215666524e5caa05dbd Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Mon, 28 Apr 2025 12:16:15 -0700 Subject: [PATCH 05/31] temporarily downgrade sqlalchemy --- poetry.lock | 146 ++++++++++++++++++++++--------------------------- pyproject.toml | 4 +- 2 files changed, 66 insertions(+), 84 deletions(-) diff --git a/poetry.lock b/poetry.lock index 362e845..eaf20d2 100644 --- a/poetry.lock +++ b/poetry.lock @@ -165,7 +165,7 @@ description = "Lightweight in-process concurrent programming" optional = false python-versions = ">=3.9" groups = ["main", "test"] -markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")" +markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\"" files = [ {file = "greenlet-3.2.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:777c1281aa7c786738683e302db0f55eb4b0077c20f1dc53db8852ffaea0a6b0"}, {file = "greenlet-3.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3059c6f286b53ea4711745146ffe5a5c5ff801f62f6c56949446e0f6461f8157"}, @@ -629,99 +629,81 @@ files = [ [[package]] name = "sqlalchemy" -version = "2.0.40" +version = "1.4.54" description = "Database Abstraction Library" optional = false -python-versions = ">=3.7" +python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" groups = ["main", "test"] files = [ - {file = "SQLAlchemy-2.0.40-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ae9597cab738e7cc823f04a704fb754a9249f0b6695a6aeb63b74055cd417a96"}, - {file = "SQLAlchemy-2.0.40-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37a5c21ab099a83d669ebb251fddf8f5cee4d75ea40a5a1653d9c43d60e20867"}, - {file = "SQLAlchemy-2.0.40-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bece9527f5a98466d67fb5d34dc560c4da964240d8b09024bb21c1246545e04e"}, - {file = "SQLAlchemy-2.0.40-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:8bb131ffd2165fae48162c7bbd0d97c84ab961deea9b8bab16366543deeab625"}, - {file = "SQLAlchemy-2.0.40-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:9408fd453d5f8990405cc9def9af46bfbe3183e6110401b407c2d073c3388f47"}, - {file = "SQLAlchemy-2.0.40-cp37-cp37m-win32.whl", hash = "sha256:00a494ea6f42a44c326477b5bee4e0fc75f6a80c01570a32b57e89cf0fbef85a"}, - {file = "SQLAlchemy-2.0.40-cp37-cp37m-win_amd64.whl", hash = "sha256:c7b927155112ac858357ccf9d255dd8c044fd9ad2dc6ce4c4149527c901fa4c3"}, - {file = "sqlalchemy-2.0.40-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f1ea21bef99c703f44444ad29c2c1b6bd55d202750b6de8e06a955380f4725d7"}, - {file = "sqlalchemy-2.0.40-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:afe63b208153f3a7a2d1a5b9df452b0673082588933e54e7c8aac457cf35e758"}, - {file = "sqlalchemy-2.0.40-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8aae085ea549a1eddbc9298b113cffb75e514eadbb542133dd2b99b5fb3b6af"}, - {file = "sqlalchemy-2.0.40-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ea9181284754d37db15156eb7be09c86e16e50fbe77610e9e7bee09291771a1"}, - {file = "sqlalchemy-2.0.40-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5434223b795be5c5ef8244e5ac98056e290d3a99bdcc539b916e282b160dda00"}, - {file = "sqlalchemy-2.0.40-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:15d08d5ef1b779af6a0909b97be6c1fd4298057504eb6461be88bd1696cb438e"}, - {file = "sqlalchemy-2.0.40-cp310-cp310-win32.whl", hash = "sha256:cd2f75598ae70bcfca9117d9e51a3b06fe29edd972fdd7fd57cc97b4dbf3b08a"}, - {file = "sqlalchemy-2.0.40-cp310-cp310-win_amd64.whl", hash = "sha256:2cbafc8d39ff1abdfdda96435f38fab141892dc759a2165947d1a8fffa7ef596"}, - {file = "sqlalchemy-2.0.40-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f6bacab7514de6146a1976bc56e1545bee247242fab030b89e5f70336fc0003e"}, - {file = "sqlalchemy-2.0.40-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5654d1ac34e922b6c5711631f2da497d3a7bffd6f9f87ac23b35feea56098011"}, - {file = "sqlalchemy-2.0.40-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35904d63412db21088739510216e9349e335f142ce4a04b69e2528020ee19ed4"}, - {file = "sqlalchemy-2.0.40-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c7a80ed86d6aaacb8160a1caef6680d4ddd03c944d985aecee940d168c411d1"}, - {file = "sqlalchemy-2.0.40-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:519624685a51525ddaa7d8ba8265a1540442a2ec71476f0e75241eb8263d6f51"}, - {file = "sqlalchemy-2.0.40-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2ee5f9999a5b0e9689bed96e60ee53c3384f1a05c2dd8068cc2e8361b0df5b7a"}, - {file = "sqlalchemy-2.0.40-cp311-cp311-win32.whl", hash = "sha256:c0cae71e20e3c02c52f6b9e9722bca70e4a90a466d59477822739dc31ac18b4b"}, - {file = "sqlalchemy-2.0.40-cp311-cp311-win_amd64.whl", hash = "sha256:574aea2c54d8f1dd1699449f332c7d9b71c339e04ae50163a3eb5ce4c4325ee4"}, - {file = "sqlalchemy-2.0.40-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9d3b31d0a1c44b74d3ae27a3de422dfccd2b8f0b75e51ecb2faa2bf65ab1ba0d"}, - {file = "sqlalchemy-2.0.40-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:37f7a0f506cf78c80450ed1e816978643d3969f99c4ac6b01104a6fe95c5490a"}, - {file = "sqlalchemy-2.0.40-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bb933a650323e476a2e4fbef8997a10d0003d4da996aad3fd7873e962fdde4d"}, - {file = "sqlalchemy-2.0.40-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6959738971b4745eea16f818a2cd086fb35081383b078272c35ece2b07012716"}, - {file = "sqlalchemy-2.0.40-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:110179728e442dae85dd39591beb74072ae4ad55a44eda2acc6ec98ead80d5f2"}, - {file = "sqlalchemy-2.0.40-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8040680eaacdce4d635f12c55c714f3d4c7f57da2bc47a01229d115bd319191"}, - {file = "sqlalchemy-2.0.40-cp312-cp312-win32.whl", hash = "sha256:650490653b110905c10adac69408380688cefc1f536a137d0d69aca1069dc1d1"}, - {file = "sqlalchemy-2.0.40-cp312-cp312-win_amd64.whl", hash = "sha256:2be94d75ee06548d2fc591a3513422b873490efb124048f50556369a834853b0"}, - {file = "sqlalchemy-2.0.40-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:915866fd50dd868fdcc18d61d8258db1bf9ed7fbd6dfec960ba43365952f3b01"}, - {file = "sqlalchemy-2.0.40-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a4c5a2905a9ccdc67a8963e24abd2f7afcd4348829412483695c59e0af9a705"}, - {file = "sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55028d7a3ebdf7ace492fab9895cbc5270153f75442a0472d8516e03159ab364"}, - {file = "sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cfedff6878b0e0d1d0a50666a817ecd85051d12d56b43d9d425455e608b5ba0"}, - {file = "sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bb19e30fdae77d357ce92192a3504579abe48a66877f476880238a962e5b96db"}, - {file = "sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:16d325ea898f74b26ffcd1cf8c593b0beed8714f0317df2bed0d8d1de05a8f26"}, - {file = "sqlalchemy-2.0.40-cp313-cp313-win32.whl", hash = "sha256:a669cbe5be3c63f75bcbee0b266779706f1a54bcb1000f302685b87d1b8c1500"}, - {file = "sqlalchemy-2.0.40-cp313-cp313-win_amd64.whl", hash = "sha256:641ee2e0834812d657862f3a7de95e0048bdcb6c55496f39c6fa3d435f6ac6ad"}, - {file = "sqlalchemy-2.0.40-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:50f5885bbed261fc97e2e66c5156244f9704083a674b8d17f24c72217d29baf5"}, - {file = "sqlalchemy-2.0.40-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cf0e99cdb600eabcd1d65cdba0d3c91418fee21c4aa1d28db47d095b1064a7d8"}, - {file = "sqlalchemy-2.0.40-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe147fcd85aaed53ce90645c91ed5fca0cc88a797314c70dfd9d35925bd5d106"}, - {file = "sqlalchemy-2.0.40-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baf7cee56bd552385c1ee39af360772fbfc2f43be005c78d1140204ad6148438"}, - {file = "sqlalchemy-2.0.40-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4aeb939bcac234b88e2d25d5381655e8353fe06b4e50b1c55ecffe56951d18c2"}, - {file = "sqlalchemy-2.0.40-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c268b5100cfeaa222c40f55e169d484efa1384b44bf9ca415eae6d556f02cb08"}, - {file = "sqlalchemy-2.0.40-cp38-cp38-win32.whl", hash = "sha256:46628ebcec4f23a1584fb52f2abe12ddb00f3bb3b7b337618b80fc1b51177aff"}, - {file = "sqlalchemy-2.0.40-cp38-cp38-win_amd64.whl", hash = "sha256:7e0505719939e52a7b0c65d20e84a6044eb3712bb6f239c6b1db77ba8e173a37"}, - {file = "sqlalchemy-2.0.40-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c884de19528e0fcd9dc34ee94c810581dd6e74aef75437ff17e696c2bfefae3e"}, - {file = "sqlalchemy-2.0.40-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1abb387710283fc5983d8a1209d9696a4eae9db8d7ac94b402981fe2fe2e39ad"}, - {file = "sqlalchemy-2.0.40-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cfa124eda500ba4b0d3afc3e91ea27ed4754e727c7f025f293a22f512bcd4c9"}, - {file = "sqlalchemy-2.0.40-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b6b28d303b9d57c17a5164eb1fd2d5119bb6ff4413d5894e74873280483eeb5"}, - {file = "sqlalchemy-2.0.40-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b5a5bbe29c10c5bfd63893747a1bf6f8049df607638c786252cb9243b86b6706"}, - {file = "sqlalchemy-2.0.40-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f0fda83e113bb0fb27dc003685f32a5dcb99c9c4f41f4fa0838ac35265c23b5c"}, - {file = "sqlalchemy-2.0.40-cp39-cp39-win32.whl", hash = "sha256:957f8d85d5e834397ef78a6109550aeb0d27a53b5032f7a57f2451e1adc37e98"}, - {file = "sqlalchemy-2.0.40-cp39-cp39-win_amd64.whl", hash = "sha256:1ffdf9c91428e59744f8e6f98190516f8e1d05eec90e936eb08b257332c5e870"}, - {file = "sqlalchemy-2.0.40-py3-none-any.whl", hash = "sha256:32587e2e1e359276957e6fe5dad089758bc042a971a8a09ae8ecf7a8fe23d07a"}, - {file = "sqlalchemy-2.0.40.tar.gz", hash = "sha256:d827099289c64589418ebbcaead0145cd19f4e3e8a93919a0100247af245fa00"}, + {file = "SQLAlchemy-1.4.54-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:af00236fe21c4d4f4c227b6ccc19b44c594160cc3ff28d104cdce85855369277"}, + {file = "SQLAlchemy-1.4.54-cp310-cp310-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1183599e25fa38a1a322294b949da02b4f0da13dbc2688ef9dbe746df573f8a6"}, + {file = "SQLAlchemy-1.4.54-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1990d5a6a5dc358a0894c8ca02043fb9a5ad9538422001fb2826e91c50f1d539"}, + {file = "SQLAlchemy-1.4.54-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:14b3f4783275339170984cadda66e3ec011cce87b405968dc8d51cf0f9997b0d"}, + {file = "SQLAlchemy-1.4.54-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b24364150738ce488333b3fb48bfa14c189a66de41cd632796fbcacb26b4585"}, + {file = "SQLAlchemy-1.4.54-cp310-cp310-win32.whl", hash = "sha256:a8a72259a1652f192c68377be7011eac3c463e9892ef2948828c7d58e4829988"}, + {file = "SQLAlchemy-1.4.54-cp310-cp310-win_amd64.whl", hash = "sha256:b67589f7955924865344e6eacfdcf70675e64f36800a576aa5e961f0008cde2a"}, + {file = "SQLAlchemy-1.4.54-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b05e0626ec1c391432eabb47a8abd3bf199fb74bfde7cc44a26d2b1b352c2c6e"}, + {file = "SQLAlchemy-1.4.54-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13e91d6892b5fcb94a36ba061fb7a1f03d0185ed9d8a77c84ba389e5bb05e936"}, + {file = "SQLAlchemy-1.4.54-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb59a11689ff3c58e7652260127f9e34f7f45478a2f3ef831ab6db7bcd72108f"}, + {file = "SQLAlchemy-1.4.54-cp311-cp311-win32.whl", hash = "sha256:1390ca2d301a2708fd4425c6d75528d22f26b8f5cbc9faba1ddca136671432bc"}, + {file = "SQLAlchemy-1.4.54-cp311-cp311-win_amd64.whl", hash = "sha256:2b37931eac4b837c45e2522066bda221ac6d80e78922fb77c75eb12e4dbcdee5"}, + {file = "SQLAlchemy-1.4.54-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3f01c2629a7d6b30d8afe0326b8c649b74825a0e1ebdcb01e8ffd1c920deb07d"}, + {file = "SQLAlchemy-1.4.54-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c24dd161c06992ed16c5e528a75878edbaeced5660c3db88c820f1f0d3fe1f4"}, + {file = "SQLAlchemy-1.4.54-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5e0d47d619c739bdc636bbe007da4519fc953393304a5943e0b5aec96c9877c"}, + {file = "SQLAlchemy-1.4.54-cp312-cp312-win32.whl", hash = "sha256:12bc0141b245918b80d9d17eca94663dbd3f5266ac77a0be60750f36102bbb0f"}, + {file = "SQLAlchemy-1.4.54-cp312-cp312-win_amd64.whl", hash = "sha256:f941aaf15f47f316123e1933f9ea91a6efda73a161a6ab6046d1cde37be62c88"}, + {file = "SQLAlchemy-1.4.54-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:a41611835010ed4ea4c7aed1da5b58aac78ee7e70932a91ed2705a7b38e40f52"}, + {file = "SQLAlchemy-1.4.54-cp36-cp36m-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e8c1b9ecaf9f2590337d5622189aeb2f0dbc54ba0232fa0856cf390957584a9"}, + {file = "SQLAlchemy-1.4.54-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0de620f978ca273ce027769dc8db7e6ee72631796187adc8471b3c76091b809e"}, + {file = "SQLAlchemy-1.4.54-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c5a2530400a6e7e68fd1552a55515de6a4559122e495f73554a51cedafc11669"}, + {file = "SQLAlchemy-1.4.54-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cf7076c8578b3de4e43a046cc7a1af8466e1c3f5e64167189fe8958a4f9c02"}, + {file = "SQLAlchemy-1.4.54-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:f1e1b92ee4ee9ffc68624ace218b89ca5ca667607ccee4541a90cc44999b9aea"}, + {file = "SQLAlchemy-1.4.54-cp37-cp37m-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41cffc63c7c83dfc30c4cab5b4308ba74440a9633c4509c51a0c52431fb0f8ab"}, + {file = "SQLAlchemy-1.4.54-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5933c45d11cbd9694b1540aa9076816cc7406964c7b16a380fd84d3a5fe3241"}, + {file = "SQLAlchemy-1.4.54-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cafe0ba3a96d0845121433cffa2b9232844a2609fce694fcc02f3f31214ece28"}, + {file = "SQLAlchemy-1.4.54-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a19f816f4702d7b1951d7576026c7124b9bfb64a9543e571774cf517b7a50b29"}, + {file = "SQLAlchemy-1.4.54-cp37-cp37m-win32.whl", hash = "sha256:76c2ba7b5a09863d0a8166fbc753af96d561818c572dbaf697c52095938e7be4"}, + {file = "SQLAlchemy-1.4.54-cp37-cp37m-win_amd64.whl", hash = "sha256:a86b0e4be775902a5496af4fb1b60d8a2a457d78f531458d294360b8637bb014"}, + {file = "SQLAlchemy-1.4.54-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:a49730afb716f3f675755afec109895cab95bc9875db7ffe2e42c1b1c6279482"}, + {file = "SQLAlchemy-1.4.54-cp38-cp38-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26e78444bc77d089e62874dc74df05a5c71f01ac598010a327881a48408d0064"}, + {file = "SQLAlchemy-1.4.54-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02d2ecb9508f16ab9c5af466dfe5a88e26adf2e1a8d1c56eb616396ccae2c186"}, + {file = "SQLAlchemy-1.4.54-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:394b0135900b62dbf63e4809cdc8ac923182af2816d06ea61cd6763943c2cc05"}, + {file = "SQLAlchemy-1.4.54-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ed3576675c187e3baa80b02c4c9d0edfab78eff4e89dd9da736b921333a2432"}, + {file = "SQLAlchemy-1.4.54-cp38-cp38-win32.whl", hash = "sha256:fc9ffd9a38e21fad3e8c5a88926d57f94a32546e937e0be46142b2702003eba7"}, + {file = "SQLAlchemy-1.4.54-cp38-cp38-win_amd64.whl", hash = "sha256:a01bc25eb7a5688656c8770f931d5cb4a44c7de1b3cec69b84cc9745d1e4cc10"}, + {file = "SQLAlchemy-1.4.54-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:0b76bbb1cbae618d10679be8966f6d66c94f301cfc15cb49e2f2382563fb6efb"}, + {file = "SQLAlchemy-1.4.54-cp39-cp39-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdb2886c0be2c6c54d0651d5a61c29ef347e8eec81fd83afebbf7b59b80b7393"}, + {file = "SQLAlchemy-1.4.54-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:954816850777ac234a4e32b8c88ac1f7847088a6e90cfb8f0e127a1bf3feddff"}, + {file = "SQLAlchemy-1.4.54-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1d83cd1cc03c22d922ec94d0d5f7b7c96b1332f5e122e81b1a61fb22da77879a"}, + {file = "SQLAlchemy-1.4.54-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1576fba3616f79496e2f067262200dbf4aab1bb727cd7e4e006076686413c80c"}, + {file = "SQLAlchemy-1.4.54-cp39-cp39-win32.whl", hash = "sha256:3112de9e11ff1957148c6de1df2bc5cc1440ee36783412e5eedc6f53638a577d"}, + {file = "SQLAlchemy-1.4.54-cp39-cp39-win_amd64.whl", hash = "sha256:6da60fb24577f989535b8fc8b2ddc4212204aaf02e53c4c7ac94ac364150ed08"}, + {file = "sqlalchemy-1.4.54.tar.gz", hash = "sha256:4470fbed088c35dc20b78a39aaf4ae54fe81790c783b3264872a0224f437c31a"}, ] [package.dependencies] -greenlet = {version = ">=1", markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} -typing-extensions = ">=4.6.0" +greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} [package.extras] -aiomysql = ["aiomysql (>=0.2.0)", "greenlet (>=1)"] -aioodbc = ["aioodbc", "greenlet (>=1)"] -aiosqlite = ["aiosqlite", "greenlet (>=1)", "typing_extensions (!=3.10.0.1)"] -asyncio = ["greenlet (>=1)"] -asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (>=1)"] -mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10)"] +aiomysql = ["aiomysql (>=0.2.0) ; python_version >= \"3\"", "greenlet (!=0.4.17) ; python_version >= \"3\""] +aiosqlite = ["aiosqlite ; python_version >= \"3\"", "greenlet (!=0.4.17) ; python_version >= \"3\"", "typing_extensions (!=3.10.0.1)"] +asyncio = ["greenlet (!=0.4.17) ; python_version >= \"3\""] +asyncmy = ["asyncmy (>=0.2.3,!=0.2.4) ; python_version >= \"3\"", "greenlet (!=0.4.17) ; python_version >= \"3\""] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2) ; python_version >= \"3\"", "mariadb (>=1.0.1,!=1.1.2) ; python_version >= \"3\""] mssql = ["pyodbc"] -mssql-pymssql = ["pymssql"] -mssql-pyodbc = ["pyodbc"] -mypy = ["mypy (>=0.910)"] -mysql = ["mysqlclient (>=1.4.0)"] -mysql-connector = ["mysql-connector-python"] -oracle = ["cx_oracle (>=8)"] -oracle-oracledb = ["oracledb (>=1.0.1)"] +mssql-pymssql = ["pymssql", "pymssql"] +mssql-pyodbc = ["pyodbc", "pyodbc"] +mypy = ["mypy (>=0.910) ; python_version >= \"3\"", "sqlalchemy2-stubs"] +mysql = ["mysqlclient (>=1.4.0) ; python_version >= \"3\"", "mysqlclient (>=1.4.0,<2) ; python_version < \"3\""] +mysql-connector = ["mysql-connector-python", "mysql-connector-python"] +oracle = ["cx_oracle (>=7) ; python_version >= \"3\"", "cx_oracle (>=7,<8) ; python_version < \"3\""] postgresql = ["psycopg2 (>=2.7)"] -postgresql-asyncpg = ["asyncpg", "greenlet (>=1)"] -postgresql-pg8000 = ["pg8000 (>=1.29.1)"] -postgresql-psycopg = ["psycopg (>=3.0.7)"] +postgresql-asyncpg = ["asyncpg ; python_version >= \"3\"", "asyncpg ; python_version >= \"3\"", "greenlet (!=0.4.17) ; python_version >= \"3\"", "greenlet (!=0.4.17) ; python_version >= \"3\""] +postgresql-pg8000 = ["pg8000 (>=1.16.6,!=1.29.0) ; python_version >= \"3\"", "pg8000 (>=1.16.6,!=1.29.0) ; python_version >= \"3\""] postgresql-psycopg2binary = ["psycopg2-binary"] postgresql-psycopg2cffi = ["psycopg2cffi"] -postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] -pymysql = ["pymysql"] -sqlcipher = ["sqlcipher3_binary"] +pymysql = ["pymysql (<1) ; python_version < \"3\"", "pymysql ; python_version >= \"3\""] +sqlcipher = ["sqlcipher3_binary ; python_version >= \"3\""] [[package]] name = "sqlalchemy-diff" @@ -863,4 +845,4 @@ files = [ [metadata] lock-version = "2.1" python-versions = ">=3.10" -content-hash = "b6784d4221d3ebc34b5bb122e059c6580b69729d54d12eb4d5d2a32c645a5e41" +content-hash = "242b5e182e5350d370137e0fb7aac8a303be395d323a93f80ab63d24d2c4b931" diff --git a/pyproject.toml b/pyproject.toml index c074aad..73c1a14 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -12,11 +12,11 @@ authors = [ requires-python = ">=3.10" dependencies = [ "setuptools (>=79.0.1,<80.0.0)", - "sqlalchemy (>=2.0.40,<3.0.0)", "nchelpers (>=5.5.11,<6.0.0)", "pycrs (>=1.0.2,<2.0.0)", - "psycopg2 (>=2.9.10,<3.0.0)", "alembic (>=1.15.2,<2.0.0)", + "psycopg2 (>=2.9.10,<3.0.0)", + "sqlalchemy (<2.0)", ] [tool.poetry] From f395e5bef7e697ad209cd3e08f5780547457e825 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Mon, 28 Apr 2025 17:03:25 -0700 Subject: [PATCH 06/31] don't use non-numberic keys for rows --- tests/alembic-migrations/test_migrations.py | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/tests/alembic-migrations/test_migrations.py b/tests/alembic-migrations/test_migrations.py index 8d69df7..bea94a0 100644 --- a/tests/alembic-migrations/test_migrations.py +++ b/tests/alembic-migrations/test_migrations.py @@ -236,6 +236,6 @@ def test_12f290b63791_downgrade_data_migration(uri_left, alembic_config_left): assert results is not None assert len(results) == num_test_records - assert all(r['variable_alias_id'] == r['data_file_variable_id'] for r in results) - assert all(r['grid_id'] == r['data_file_variable_id'] for r in results) - assert all(r['data_file_id'] == r['data_file_variable_id'] for r in results) + assert all(r.mappings()['variable_alias_id'] == r.mappings()['data_file_variable_id'] for r in results) + assert all(r.mappings()['grid_id'] == r.mappings()['data_file_variable_id'] for r in results) + assert all(r.mappings()['data_file_id'] == r.mappings()['data_file_variable_id'] for r in results) From 94ac768f637cd42d129a983965f104a2e9615b97 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Wed, 30 Apr 2025 11:25:10 -0700 Subject: [PATCH 07/31] de-list arguments to case() --- mm_cataloguer/index_netcdf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm_cataloguer/index_netcdf.py b/mm_cataloguer/index_netcdf.py index 7cd230d..d584bee 100644 --- a/mm_cataloguer/index_netcdf.py +++ b/mm_cataloguer/index_netcdf.py @@ -562,9 +562,9 @@ def insert_spatial_ref_sys(sesh, cf, var_name): ) next_srid = ( select( - case([ + case( (max_srid.c.max_srid >= 990000, max_srid.c.max_srid + 1), - ], else_=990000).label('next_srid') + else_=990000).label('next_srid') ) .cte(name='next_srid') ) From 1c1125b7cb0a7ab6be946ad914029971a26b8aba Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Wed, 30 Apr 2025 15:19:55 -0700 Subject: [PATCH 08/31] remove redundant bind argument --- .../12f290b63791_handle_variant_sampling_geometries.py | 10 +++++----- tests/alembic-migrations/test_migrations.py | 8 ++++---- tests/mm_cataloguer/test_index.py | 4 ++-- 3 files changed, 11 insertions(+), 11 deletions(-) diff --git a/alembic/versions/12f290b63791_handle_variant_sampling_geometries.py b/alembic/versions/12f290b63791_handle_variant_sampling_geometries.py index b243b8e..b86679f 100644 --- a/alembic/versions/12f290b63791_handle_variant_sampling_geometries.py +++ b/alembic/versions/12f290b63791_handle_variant_sampling_geometries.py @@ -32,12 +32,12 @@ def copy_level_set_id_and_grid_id_to_data_file_variables_gridded(): # Adapted from https://gist.github.com/mafrosis/5e456eb16bf4cc619c959f4d6e1aa8e1 dfvs = sa.Table( 'data_file_variables', - sa.MetaData(bind=op.get_bind()), + sa.MetaData(), autoload_with=op.get_bind() ) dfvs_gridded = sa.Table( 'data_file_variables_gridded', - sa.MetaData(bind=op.get_bind()), + sa.MetaData(), autoload_with=op.get_bind() ) op.get_bind().execute( @@ -132,12 +132,12 @@ def copy_level_set_id_and_grid_id_from_data_file_variables_gridded(): # Adapted from https://gist.github.com/mafrosis/5e456eb16bf4cc619c959f4d6e1aa8e1 dfvs = sa.Table( 'data_file_variables', - sa.MetaData(bind=op.get_bind()), + sa.MetaData(), autoload_with=op.get_bind() ) dfvs_gridded = sa.Table( 'data_file_variables_gridded', - sa.MetaData(bind=op.get_bind()), + sa.MetaData(), autoload_with=op.get_bind() ) if get_dialect() == 'sqlite': @@ -169,7 +169,7 @@ def copy_level_set_id_and_grid_id_from_data_file_variables_gridded(): def delete_dsg_time_series_data_file_variables(): dfvs = sa.Table( 'data_file_variables', - sa.MetaData(bind=op.get_bind()), + sa.MetaData(), autoload_with=op.get_bind() ) dfvs.delete().where(dfvs.c.geometry_type == 'dsg_time_series') diff --git a/tests/alembic-migrations/test_migrations.py b/tests/alembic-migrations/test_migrations.py index bea94a0..b9a2e2a 100644 --- a/tests/alembic-migrations/test_migrations.py +++ b/tests/alembic-migrations/test_migrations.py @@ -89,7 +89,7 @@ def test_12f290b63791_upgrade_data_migration(uri_left, alembic_config_left): uri_left, alembic_config_left, revision='614911daf883') # Define minimal set of tables needed to test migration - meta_data = MetaData(bind=engine) + meta_data = MetaData() variable_aliases = Table('variable_aliases', meta_data, autoload_with=engine) grids = Table('grids', meta_data, autoload_with=engine) data_files = Table('data_files', meta_data, autoload_with=engine) @@ -236,6 +236,6 @@ def test_12f290b63791_downgrade_data_migration(uri_left, alembic_config_left): assert results is not None assert len(results) == num_test_records - assert all(r.mappings()['variable_alias_id'] == r.mappings()['data_file_variable_id'] for r in results) - assert all(r.mappings()['grid_id'] == r.mappings()['data_file_variable_id'] for r in results) - assert all(r.mappings()['data_file_id'] == r.mappings()['data_file_variable_id'] for r in results) + assert all(r._mapping['variable_alias_id'] == r._mapping['data_file_variable_id'] for r in results) + assert all(r._mapping['grid_id'] == r._mapping['data_file_variable_id'] for r in results) + assert all(r._mapping['data_file_id'] == r._mapping['data_file_variable_id'] for r in results) diff --git a/tests/mm_cataloguer/test_index.py b/tests/mm_cataloguer/test_index.py index 05d135b..b9518d0 100644 --- a/tests/mm_cataloguer/test_index.py +++ b/tests/mm_cataloguer/test_index.py @@ -32,7 +32,7 @@ from dateutil.relativedelta import relativedelta -from sqlalchemy import func +from sqlalchemy import func, text import pycrs @@ -167,7 +167,7 @@ def print_query_results(session, query, title=None): if title: print(title) print('-' * len(title)) - result = session.execute(query) + result = session.execute(text(query)) for row in result: print(row) From 24197f55c5b2923aace6a102e18c55730fa4d6b7 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Wed, 30 Apr 2025 16:41:36 -0700 Subject: [PATCH 09/31] execute statements on Connections --- tests/alembic-migrations/test_migrations.py | 8 ++++---- tests/conftest.py | 2 +- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/tests/alembic-migrations/test_migrations.py b/tests/alembic-migrations/test_migrations.py index b9a2e2a..9983518 100644 --- a/tests/alembic-migrations/test_migrations.py +++ b/tests/alembic-migrations/test_migrations.py @@ -55,7 +55,7 @@ def test_model_and_migration_schemas_are_the_same( """ prepare_schema_from_migrations(uri_left, alembic_config_left) engine = create_engine(uri_right) - engine.execute(text('create extension postgis')) + engine.connect().execute(text('create extension postgis')) prepare_schema_from_models(uri_right, Base) result = compare( @@ -137,7 +137,7 @@ def test_12f290b63791_upgrade_data_migration(uri_left, alembic_config_left): range_max=10.0, ) ]: - engine.execute(stmt) + engine.connect().execute(stmt) # Run upgrade migration command.upgrade(alembic_config_left, '+1') @@ -226,11 +226,11 @@ def test_12f290b63791_downgrade_data_migration(uri_left, alembic_config_left): command.downgrade(alembic_config_left, '-1') # Define minimal set of tables needed to test migration - meta_data = MetaData(bind=engine) + meta_data = MetaData() data_file_variables = Table('data_file_variables', meta_data, autoload_with=engine) # Check data results of migration. - results = list(engine.execute( + results = list(engine.connect().execute( data_file_variables.select() )) diff --git a/tests/conftest.py b/tests/conftest.py index 67ef0de..bd0cfad 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -241,7 +241,7 @@ def ensemble2(): # Database initialization def init_database(engine): - engine.execute(text("create extension postgis")) + engine.connect().execute(text("create extension postgis")) # Session-scoped databases, engines, session factories, and derived sessions From 8860e047b74f879353d1099c9e3a57c8f88e957d Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Thu, 1 May 2025 10:51:07 -0700 Subject: [PATCH 10/31] explicitly begin sessions --- tests/alembic-migrations/test_migrations.py | 104 ++++++++++---------- tests/conftest.py | 4 +- 2 files changed, 57 insertions(+), 51 deletions(-) diff --git a/tests/alembic-migrations/test_migrations.py b/tests/alembic-migrations/test_migrations.py index 9983518..3d31f6c 100644 --- a/tests/alembic-migrations/test_migrations.py +++ b/tests/alembic-migrations/test_migrations.py @@ -55,7 +55,9 @@ def test_model_and_migration_schemas_are_the_same( """ prepare_schema_from_migrations(uri_left, alembic_config_left) engine = create_engine(uri_right) - engine.connect().execute(text('create extension postgis')) + with engine.connect() as connection: + with connection.begin(): + connection.execute(text('create extension postgis')) prepare_schema_from_models(uri_right, Base) result = compare( @@ -98,46 +100,48 @@ def test_12f290b63791_upgrade_data_migration(uri_left, alembic_config_left): # Insert minimal data needed to test migration: Several instances of each of # variable_aliases, grids, data_files, associated to a data_file_variables. num_test_records = 3 - for i in range(0, num_test_records): - for stmt in [ - variable_aliases.insert().values( - variable_alias_id=i, - variable_long_name=name('var', i), - variable_standard_name=name('var', i), - variable_units='foo', - ), - grids.insert().values( - grid_id=i, - xc_origin=0.0, - xc_grid_step=1.0, - xc_count=10, - xc_units='xc_units', - yc_origin=0.0, - yc_grid_step=1.0, - yc_count=10, - yc_units='yc_units', - evenly_spaced_y=True, - ), - data_files.insert().values( - data_file_id=i, - filename=name('filename', i), - first_1mib_md5sum='first_1mib_md5sum', - unique_id=name('unique_id', i), - x_dim_name='x_dim_name', - y_dim_name='y_dim_name', - index_time=datetime.datetime.now(), - ), - data_file_variables.insert().values( - data_file_variable_id=i, - data_file_id=i, - variable_alias_id=i, - grid_id=i, - netcdf_variable_name=name('var', i), - range_min=0.0, - range_max=10.0, - ) - ]: - engine.connect().execute(stmt) + with engine.connect() as connection: + with connection.begin(): + for i in range(0, num_test_records): + for stmt in [ + variable_aliases.insert().values( + variable_alias_id=i, + variable_long_name=name('var', i), + variable_standard_name=name('var', i), + variable_units='foo', + ), + grids.insert().values( + grid_id=i, + xc_origin=0.0, + xc_grid_step=1.0, + xc_count=10, + xc_units='xc_units', + yc_origin=0.0, + yc_grid_step=1.0, + yc_count=10, + yc_units='yc_units', + evenly_spaced_y=True, + ), + data_files.insert().values( + data_file_id=i, + filename=name('filename', i), + first_1mib_md5sum='first_1mib_md5sum', + unique_id=name('unique_id', i), + x_dim_name='x_dim_name', + y_dim_name='y_dim_name', + index_time=datetime.datetime.now(), + ), + data_file_variables.insert().values( + data_file_variable_id=i, + data_file_id=i, + variable_alias_id=i, + grid_id=i, + netcdf_variable_name=name('var', i), + range_min=0.0, + range_max=10.0, + ) + ]: + connection.execute(stmt) # Run upgrade migration command.upgrade(alembic_config_left, '+1') @@ -230,12 +234,12 @@ def test_12f290b63791_downgrade_data_migration(uri_left, alembic_config_left): data_file_variables = Table('data_file_variables', meta_data, autoload_with=engine) # Check data results of migration. - results = list(engine.connect().execute( - data_file_variables.select() - )) - - assert results is not None - assert len(results) == num_test_records - assert all(r._mapping['variable_alias_id'] == r._mapping['data_file_variable_id'] for r in results) - assert all(r._mapping['grid_id'] == r._mapping['data_file_variable_id'] for r in results) - assert all(r._mapping['data_file_id'] == r._mapping['data_file_variable_id'] for r in results) + with engine.connect() as connection: + with connection.begin(): + results = list(connection.execute(data_file_variables.select())) + + assert results is not None + assert len(results) == num_test_records + assert all(r._mapping['variable_alias_id'] == r._mapping['data_file_variable_id'] for r in results) + assert all(r._mapping['grid_id'] == r._mapping['data_file_variable_id'] for r in results) + assert all(r._mapping['data_file_id'] == r._mapping['data_file_variable_id'] for r in results) diff --git a/tests/conftest.py b/tests/conftest.py index bd0cfad..ec52477 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -241,7 +241,9 @@ def ensemble2(): # Database initialization def init_database(engine): - engine.connect().execute(text("create extension postgis")) + with engine.connect() as connection: + with connection.begin(): + connection.execute(text("create extension postgis")) # Session-scoped databases, engines, session factories, and derived sessions From 3abd776e731934136880bb6fb889fb06d4ff8ab2 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Thu, 1 May 2025 11:39:23 -0700 Subject: [PATCH 11/31] update to sqlalchemy 2.0! --- poetry.lock | 146 +++++++++++++++++++++++++++---------------------- pyproject.toml | 2 +- 2 files changed, 83 insertions(+), 65 deletions(-) diff --git a/poetry.lock b/poetry.lock index eaf20d2..b32a8c5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -165,7 +165,7 @@ description = "Lightweight in-process concurrent programming" optional = false python-versions = ">=3.9" groups = ["main", "test"] -markers = "platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\"" +markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")" files = [ {file = "greenlet-3.2.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:777c1281aa7c786738683e302db0f55eb4b0077c20f1dc53db8852ffaea0a6b0"}, {file = "greenlet-3.2.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3059c6f286b53ea4711745146ffe5a5c5ff801f62f6c56949446e0f6461f8157"}, @@ -629,81 +629,99 @@ files = [ [[package]] name = "sqlalchemy" -version = "1.4.54" +version = "2.0.40" description = "Database Abstraction Library" optional = false -python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,>=2.7" +python-versions = ">=3.7" groups = ["main", "test"] files = [ - {file = "SQLAlchemy-1.4.54-cp310-cp310-macosx_12_0_x86_64.whl", hash = "sha256:af00236fe21c4d4f4c227b6ccc19b44c594160cc3ff28d104cdce85855369277"}, - {file = "SQLAlchemy-1.4.54-cp310-cp310-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1183599e25fa38a1a322294b949da02b4f0da13dbc2688ef9dbe746df573f8a6"}, - {file = "SQLAlchemy-1.4.54-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1990d5a6a5dc358a0894c8ca02043fb9a5ad9538422001fb2826e91c50f1d539"}, - {file = "SQLAlchemy-1.4.54-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:14b3f4783275339170984cadda66e3ec011cce87b405968dc8d51cf0f9997b0d"}, - {file = "SQLAlchemy-1.4.54-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6b24364150738ce488333b3fb48bfa14c189a66de41cd632796fbcacb26b4585"}, - {file = "SQLAlchemy-1.4.54-cp310-cp310-win32.whl", hash = "sha256:a8a72259a1652f192c68377be7011eac3c463e9892ef2948828c7d58e4829988"}, - {file = "SQLAlchemy-1.4.54-cp310-cp310-win_amd64.whl", hash = "sha256:b67589f7955924865344e6eacfdcf70675e64f36800a576aa5e961f0008cde2a"}, - {file = "SQLAlchemy-1.4.54-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:b05e0626ec1c391432eabb47a8abd3bf199fb74bfde7cc44a26d2b1b352c2c6e"}, - {file = "SQLAlchemy-1.4.54-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:13e91d6892b5fcb94a36ba061fb7a1f03d0185ed9d8a77c84ba389e5bb05e936"}, - {file = "SQLAlchemy-1.4.54-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fb59a11689ff3c58e7652260127f9e34f7f45478a2f3ef831ab6db7bcd72108f"}, - {file = "SQLAlchemy-1.4.54-cp311-cp311-win32.whl", hash = "sha256:1390ca2d301a2708fd4425c6d75528d22f26b8f5cbc9faba1ddca136671432bc"}, - {file = "SQLAlchemy-1.4.54-cp311-cp311-win_amd64.whl", hash = "sha256:2b37931eac4b837c45e2522066bda221ac6d80e78922fb77c75eb12e4dbcdee5"}, - {file = "SQLAlchemy-1.4.54-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:3f01c2629a7d6b30d8afe0326b8c649b74825a0e1ebdcb01e8ffd1c920deb07d"}, - {file = "SQLAlchemy-1.4.54-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:9c24dd161c06992ed16c5e528a75878edbaeced5660c3db88c820f1f0d3fe1f4"}, - {file = "SQLAlchemy-1.4.54-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b5e0d47d619c739bdc636bbe007da4519fc953393304a5943e0b5aec96c9877c"}, - {file = "SQLAlchemy-1.4.54-cp312-cp312-win32.whl", hash = "sha256:12bc0141b245918b80d9d17eca94663dbd3f5266ac77a0be60750f36102bbb0f"}, - {file = "SQLAlchemy-1.4.54-cp312-cp312-win_amd64.whl", hash = "sha256:f941aaf15f47f316123e1933f9ea91a6efda73a161a6ab6046d1cde37be62c88"}, - {file = "SQLAlchemy-1.4.54-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:a41611835010ed4ea4c7aed1da5b58aac78ee7e70932a91ed2705a7b38e40f52"}, - {file = "SQLAlchemy-1.4.54-cp36-cp36m-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1e8c1b9ecaf9f2590337d5622189aeb2f0dbc54ba0232fa0856cf390957584a9"}, - {file = "SQLAlchemy-1.4.54-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0de620f978ca273ce027769dc8db7e6ee72631796187adc8471b3c76091b809e"}, - {file = "SQLAlchemy-1.4.54-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:c5a2530400a6e7e68fd1552a55515de6a4559122e495f73554a51cedafc11669"}, - {file = "SQLAlchemy-1.4.54-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d0cf7076c8578b3de4e43a046cc7a1af8466e1c3f5e64167189fe8958a4f9c02"}, - {file = "SQLAlchemy-1.4.54-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:f1e1b92ee4ee9ffc68624ace218b89ca5ca667607ccee4541a90cc44999b9aea"}, - {file = "SQLAlchemy-1.4.54-cp37-cp37m-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:41cffc63c7c83dfc30c4cab5b4308ba74440a9633c4509c51a0c52431fb0f8ab"}, - {file = "SQLAlchemy-1.4.54-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:b5933c45d11cbd9694b1540aa9076816cc7406964c7b16a380fd84d3a5fe3241"}, - {file = "SQLAlchemy-1.4.54-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:cafe0ba3a96d0845121433cffa2b9232844a2609fce694fcc02f3f31214ece28"}, - {file = "SQLAlchemy-1.4.54-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a19f816f4702d7b1951d7576026c7124b9bfb64a9543e571774cf517b7a50b29"}, - {file = "SQLAlchemy-1.4.54-cp37-cp37m-win32.whl", hash = "sha256:76c2ba7b5a09863d0a8166fbc753af96d561818c572dbaf697c52095938e7be4"}, - {file = "SQLAlchemy-1.4.54-cp37-cp37m-win_amd64.whl", hash = "sha256:a86b0e4be775902a5496af4fb1b60d8a2a457d78f531458d294360b8637bb014"}, - {file = "SQLAlchemy-1.4.54-cp38-cp38-macosx_12_0_x86_64.whl", hash = "sha256:a49730afb716f3f675755afec109895cab95bc9875db7ffe2e42c1b1c6279482"}, - {file = "SQLAlchemy-1.4.54-cp38-cp38-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26e78444bc77d089e62874dc74df05a5c71f01ac598010a327881a48408d0064"}, - {file = "SQLAlchemy-1.4.54-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:02d2ecb9508f16ab9c5af466dfe5a88e26adf2e1a8d1c56eb616396ccae2c186"}, - {file = "SQLAlchemy-1.4.54-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:394b0135900b62dbf63e4809cdc8ac923182af2816d06ea61cd6763943c2cc05"}, - {file = "SQLAlchemy-1.4.54-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ed3576675c187e3baa80b02c4c9d0edfab78eff4e89dd9da736b921333a2432"}, - {file = "SQLAlchemy-1.4.54-cp38-cp38-win32.whl", hash = "sha256:fc9ffd9a38e21fad3e8c5a88926d57f94a32546e937e0be46142b2702003eba7"}, - {file = "SQLAlchemy-1.4.54-cp38-cp38-win_amd64.whl", hash = "sha256:a01bc25eb7a5688656c8770f931d5cb4a44c7de1b3cec69b84cc9745d1e4cc10"}, - {file = "SQLAlchemy-1.4.54-cp39-cp39-macosx_12_0_x86_64.whl", hash = "sha256:0b76bbb1cbae618d10679be8966f6d66c94f301cfc15cb49e2f2382563fb6efb"}, - {file = "SQLAlchemy-1.4.54-cp39-cp39-manylinux1_x86_64.manylinux2010_x86_64.manylinux_2_12_x86_64.manylinux_2_5_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdb2886c0be2c6c54d0651d5a61c29ef347e8eec81fd83afebbf7b59b80b7393"}, - {file = "SQLAlchemy-1.4.54-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:954816850777ac234a4e32b8c88ac1f7847088a6e90cfb8f0e127a1bf3feddff"}, - {file = "SQLAlchemy-1.4.54-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:1d83cd1cc03c22d922ec94d0d5f7b7c96b1332f5e122e81b1a61fb22da77879a"}, - {file = "SQLAlchemy-1.4.54-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1576fba3616f79496e2f067262200dbf4aab1bb727cd7e4e006076686413c80c"}, - {file = "SQLAlchemy-1.4.54-cp39-cp39-win32.whl", hash = "sha256:3112de9e11ff1957148c6de1df2bc5cc1440ee36783412e5eedc6f53638a577d"}, - {file = "SQLAlchemy-1.4.54-cp39-cp39-win_amd64.whl", hash = "sha256:6da60fb24577f989535b8fc8b2ddc4212204aaf02e53c4c7ac94ac364150ed08"}, - {file = "sqlalchemy-1.4.54.tar.gz", hash = "sha256:4470fbed088c35dc20b78a39aaf4ae54fe81790c783b3264872a0224f437c31a"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ae9597cab738e7cc823f04a704fb754a9249f0b6695a6aeb63b74055cd417a96"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37a5c21ab099a83d669ebb251fddf8f5cee4d75ea40a5a1653d9c43d60e20867"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bece9527f5a98466d67fb5d34dc560c4da964240d8b09024bb21c1246545e04e"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:8bb131ffd2165fae48162c7bbd0d97c84ab961deea9b8bab16366543deeab625"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:9408fd453d5f8990405cc9def9af46bfbe3183e6110401b407c2d073c3388f47"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-win32.whl", hash = "sha256:00a494ea6f42a44c326477b5bee4e0fc75f6a80c01570a32b57e89cf0fbef85a"}, + {file = "SQLAlchemy-2.0.40-cp37-cp37m-win_amd64.whl", hash = "sha256:c7b927155112ac858357ccf9d255dd8c044fd9ad2dc6ce4c4149527c901fa4c3"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:f1ea21bef99c703f44444ad29c2c1b6bd55d202750b6de8e06a955380f4725d7"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:afe63b208153f3a7a2d1a5b9df452b0673082588933e54e7c8aac457cf35e758"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a8aae085ea549a1eddbc9298b113cffb75e514eadbb542133dd2b99b5fb3b6af"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:5ea9181284754d37db15156eb7be09c86e16e50fbe77610e9e7bee09291771a1"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:5434223b795be5c5ef8244e5ac98056e290d3a99bdcc539b916e282b160dda00"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:15d08d5ef1b779af6a0909b97be6c1fd4298057504eb6461be88bd1696cb438e"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-win32.whl", hash = "sha256:cd2f75598ae70bcfca9117d9e51a3b06fe29edd972fdd7fd57cc97b4dbf3b08a"}, + {file = "sqlalchemy-2.0.40-cp310-cp310-win_amd64.whl", hash = "sha256:2cbafc8d39ff1abdfdda96435f38fab141892dc759a2165947d1a8fffa7ef596"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f6bacab7514de6146a1976bc56e1545bee247242fab030b89e5f70336fc0003e"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5654d1ac34e922b6c5711631f2da497d3a7bffd6f9f87ac23b35feea56098011"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35904d63412db21088739510216e9349e335f142ce4a04b69e2528020ee19ed4"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9c7a80ed86d6aaacb8160a1caef6680d4ddd03c944d985aecee940d168c411d1"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:519624685a51525ddaa7d8ba8265a1540442a2ec71476f0e75241eb8263d6f51"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:2ee5f9999a5b0e9689bed96e60ee53c3384f1a05c2dd8068cc2e8361b0df5b7a"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-win32.whl", hash = "sha256:c0cae71e20e3c02c52f6b9e9722bca70e4a90a466d59477822739dc31ac18b4b"}, + {file = "sqlalchemy-2.0.40-cp311-cp311-win_amd64.whl", hash = "sha256:574aea2c54d8f1dd1699449f332c7d9b71c339e04ae50163a3eb5ce4c4325ee4"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9d3b31d0a1c44b74d3ae27a3de422dfccd2b8f0b75e51ecb2faa2bf65ab1ba0d"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:37f7a0f506cf78c80450ed1e816978643d3969f99c4ac6b01104a6fe95c5490a"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0bb933a650323e476a2e4fbef8997a10d0003d4da996aad3fd7873e962fdde4d"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6959738971b4745eea16f818a2cd086fb35081383b078272c35ece2b07012716"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:110179728e442dae85dd39591beb74072ae4ad55a44eda2acc6ec98ead80d5f2"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8040680eaacdce4d635f12c55c714f3d4c7f57da2bc47a01229d115bd319191"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-win32.whl", hash = "sha256:650490653b110905c10adac69408380688cefc1f536a137d0d69aca1069dc1d1"}, + {file = "sqlalchemy-2.0.40-cp312-cp312-win_amd64.whl", hash = "sha256:2be94d75ee06548d2fc591a3513422b873490efb124048f50556369a834853b0"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:915866fd50dd868fdcc18d61d8258db1bf9ed7fbd6dfec960ba43365952f3b01"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:4a4c5a2905a9ccdc67a8963e24abd2f7afcd4348829412483695c59e0af9a705"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:55028d7a3ebdf7ace492fab9895cbc5270153f75442a0472d8516e03159ab364"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6cfedff6878b0e0d1d0a50666a817ecd85051d12d56b43d9d425455e608b5ba0"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:bb19e30fdae77d357ce92192a3504579abe48a66877f476880238a962e5b96db"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:16d325ea898f74b26ffcd1cf8c593b0beed8714f0317df2bed0d8d1de05a8f26"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-win32.whl", hash = "sha256:a669cbe5be3c63f75bcbee0b266779706f1a54bcb1000f302685b87d1b8c1500"}, + {file = "sqlalchemy-2.0.40-cp313-cp313-win_amd64.whl", hash = "sha256:641ee2e0834812d657862f3a7de95e0048bdcb6c55496f39c6fa3d435f6ac6ad"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:50f5885bbed261fc97e2e66c5156244f9704083a674b8d17f24c72217d29baf5"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:cf0e99cdb600eabcd1d65cdba0d3c91418fee21c4aa1d28db47d095b1064a7d8"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:fe147fcd85aaed53ce90645c91ed5fca0cc88a797314c70dfd9d35925bd5d106"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:baf7cee56bd552385c1ee39af360772fbfc2f43be005c78d1140204ad6148438"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:4aeb939bcac234b88e2d25d5381655e8353fe06b4e50b1c55ecffe56951d18c2"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:c268b5100cfeaa222c40f55e169d484efa1384b44bf9ca415eae6d556f02cb08"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-win32.whl", hash = "sha256:46628ebcec4f23a1584fb52f2abe12ddb00f3bb3b7b337618b80fc1b51177aff"}, + {file = "sqlalchemy-2.0.40-cp38-cp38-win_amd64.whl", hash = "sha256:7e0505719939e52a7b0c65d20e84a6044eb3712bb6f239c6b1db77ba8e173a37"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:c884de19528e0fcd9dc34ee94c810581dd6e74aef75437ff17e696c2bfefae3e"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1abb387710283fc5983d8a1209d9696a4eae9db8d7ac94b402981fe2fe2e39ad"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5cfa124eda500ba4b0d3afc3e91ea27ed4754e727c7f025f293a22f512bcd4c9"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8b6b28d303b9d57c17a5164eb1fd2d5119bb6ff4413d5894e74873280483eeb5"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:b5a5bbe29c10c5bfd63893747a1bf6f8049df607638c786252cb9243b86b6706"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:f0fda83e113bb0fb27dc003685f32a5dcb99c9c4f41f4fa0838ac35265c23b5c"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-win32.whl", hash = "sha256:957f8d85d5e834397ef78a6109550aeb0d27a53b5032f7a57f2451e1adc37e98"}, + {file = "sqlalchemy-2.0.40-cp39-cp39-win_amd64.whl", hash = "sha256:1ffdf9c91428e59744f8e6f98190516f8e1d05eec90e936eb08b257332c5e870"}, + {file = "sqlalchemy-2.0.40-py3-none-any.whl", hash = "sha256:32587e2e1e359276957e6fe5dad089758bc042a971a8a09ae8ecf7a8fe23d07a"}, + {file = "sqlalchemy-2.0.40.tar.gz", hash = "sha256:d827099289c64589418ebbcaead0145cd19f4e3e8a93919a0100247af245fa00"}, ] [package.dependencies] -greenlet = {version = "!=0.4.17", markers = "python_version >= \"3\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} +greenlet = {version = ">=1", markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")"} +typing-extensions = ">=4.6.0" [package.extras] -aiomysql = ["aiomysql (>=0.2.0) ; python_version >= \"3\"", "greenlet (!=0.4.17) ; python_version >= \"3\""] -aiosqlite = ["aiosqlite ; python_version >= \"3\"", "greenlet (!=0.4.17) ; python_version >= \"3\"", "typing_extensions (!=3.10.0.1)"] -asyncio = ["greenlet (!=0.4.17) ; python_version >= \"3\""] -asyncmy = ["asyncmy (>=0.2.3,!=0.2.4) ; python_version >= \"3\"", "greenlet (!=0.4.17) ; python_version >= \"3\""] -mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2) ; python_version >= \"3\"", "mariadb (>=1.0.1,!=1.1.2) ; python_version >= \"3\""] +aiomysql = ["aiomysql (>=0.2.0)", "greenlet (>=1)"] +aioodbc = ["aioodbc", "greenlet (>=1)"] +aiosqlite = ["aiosqlite", "greenlet (>=1)", "typing_extensions (!=3.10.0.1)"] +asyncio = ["greenlet (>=1)"] +asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (>=1)"] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5,!=1.1.10)"] mssql = ["pyodbc"] -mssql-pymssql = ["pymssql", "pymssql"] -mssql-pyodbc = ["pyodbc", "pyodbc"] -mypy = ["mypy (>=0.910) ; python_version >= \"3\"", "sqlalchemy2-stubs"] -mysql = ["mysqlclient (>=1.4.0) ; python_version >= \"3\"", "mysqlclient (>=1.4.0,<2) ; python_version < \"3\""] -mysql-connector = ["mysql-connector-python", "mysql-connector-python"] -oracle = ["cx_oracle (>=7) ; python_version >= \"3\"", "cx_oracle (>=7,<8) ; python_version < \"3\""] +mssql-pymssql = ["pymssql"] +mssql-pyodbc = ["pyodbc"] +mypy = ["mypy (>=0.910)"] +mysql = ["mysqlclient (>=1.4.0)"] +mysql-connector = ["mysql-connector-python"] +oracle = ["cx_oracle (>=8)"] +oracle-oracledb = ["oracledb (>=1.0.1)"] postgresql = ["psycopg2 (>=2.7)"] -postgresql-asyncpg = ["asyncpg ; python_version >= \"3\"", "asyncpg ; python_version >= \"3\"", "greenlet (!=0.4.17) ; python_version >= \"3\"", "greenlet (!=0.4.17) ; python_version >= \"3\""] -postgresql-pg8000 = ["pg8000 (>=1.16.6,!=1.29.0) ; python_version >= \"3\"", "pg8000 (>=1.16.6,!=1.29.0) ; python_version >= \"3\""] +postgresql-asyncpg = ["asyncpg", "greenlet (>=1)"] +postgresql-pg8000 = ["pg8000 (>=1.29.1)"] +postgresql-psycopg = ["psycopg (>=3.0.7)"] postgresql-psycopg2binary = ["psycopg2-binary"] postgresql-psycopg2cffi = ["psycopg2cffi"] -pymysql = ["pymysql (<1) ; python_version < \"3\"", "pymysql ; python_version >= \"3\""] -sqlcipher = ["sqlcipher3_binary ; python_version >= \"3\""] +postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] +pymysql = ["pymysql"] +sqlcipher = ["sqlcipher3_binary"] [[package]] name = "sqlalchemy-diff" @@ -845,4 +863,4 @@ files = [ [metadata] lock-version = "2.1" python-versions = ">=3.10" -content-hash = "242b5e182e5350d370137e0fb7aac8a303be395d323a93f80ab63d24d2c4b931" +content-hash = "e6d34ce616a47c01ade1011bf30bf1b57b3b457330baf06585a1b2dc87edc513" diff --git a/pyproject.toml b/pyproject.toml index 73c1a14..d577aba 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -16,7 +16,7 @@ dependencies = [ "pycrs (>=1.0.2,<2.0.0)", "alembic (>=1.15.2,<2.0.0)", "psycopg2 (>=2.9.10,<3.0.0)", - "sqlalchemy (<2.0)", + "sqlalchemy (>=2.0.40,<3.0.0)", ] [tool.poetry] From e44d8b27cea162cee0691665b226f4dfc5c0badd Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Thu, 1 May 2025 12:24:15 -0700 Subject: [PATCH 12/31] update CI --- .github/workflows/pypi-publish.yml | 4 ++-- .github/workflows/python-ci.yml | 33 ++++++++++-------------------- setup.py | 5 +++-- 3 files changed, 16 insertions(+), 26 deletions(-) diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index 98b0303..e888ee2 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -8,14 +8,14 @@ on: jobs: publish: - runs-on: ubuntu-20.04 + runs-on: ubuntu-22.04 steps: - uses: actions/checkout@v2 - name: Set up Python uses: actions/setup-python@v2 with: - python-version: '3.6' + python-version: '3.11' - name: Install dependencies run: | python -m pip install --upgrade pip diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 799e5ff..d99f1eb 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -9,9 +9,9 @@ jobs: strategy: matrix: python-version: - - "3.8" - - "3.9" - "3.10" + - "3.11" + - "3.12" steps: - uses: actions/checkout@v2 @@ -20,37 +20,26 @@ jobs: with: python-version: ${{ matrix.python-version }} - - name: Install dependencies + - name: Install system dependencies run: | sudo apt-get update - sudo apt-get install postgis postgresql-14 postgresql-client-14 libhdf5-serial-dev libnetcdf-dev libspatialite-dev + sudo apt-get install postgis postgresql-14 postgresql-client-14 libhdf5-serial-dev libnetcdf-dev libspatialite-dev wget - - name: Install pipenv + - name: Install poetry run: | - pip install pipenv==2022.10.25 - - - id: cache-pipenv - uses: actions/cache@v2 - with: - path: ~/.local/share/virtualenvs - key: ${{ runner.os }}-pipenv-${{ hashFiles('**/Pipfile.lock') }} + wget -O - https://install.python-poetry.org | python3 - + echo "$HOME/.local/bin" >> $GITHUB_PATH - - name: Install dependencies if changed - if: ${{ steps.cache-pipenv.outputs.cache-hit != 'true' && matrix.python-version == '3.8' }} - run: | - pipenv install --deploy --dev - - name: Re-install dependencies if alternative python version - if: ${{ matrix.python-version != '3.8' }} + - name: Install python dependencies run: | - mv Pipfile.lock do-not-use - pipenv install --python ${{ matrix.python-version }} --dev + poetry install --with=test - name: Test with pytest (full) if: github.ref == 'refs/heads/master' run: | - pipenv run py.test -m "not online" -v + poetry run py.test -v - name: Test with pytest (fast) if: github.ref != 'refs/heads/master' run: | - pipenv run py.test -m "not online and not slow" -v + poetry run py.test -m "not slow" -v \ No newline at end of file diff --git a/setup.py b/setup.py index ff25e90..cd2879c 100644 --- a/setup.py +++ b/setup.py @@ -57,8 +57,9 @@ 'Intended Audience :: Science/Research', 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', 'Operating System :: OS Independent', - 'Programming Language :: Python :: 3.6', - 'Programming Language :: Python :: 3.7', + 'Programming Language :: Python :: 3.10', + 'Programming Language :: Python :: 3.11', + 'Programming Language :: Python :: 3.12', 'Topic :: Scientific/Engineering', 'Topic :: Database', 'Topic :: Software Development :: Libraries :: Python Modules' From e86617139a11907784cdaa232187865c81fa44d4 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Fri, 2 May 2025 17:17:59 -0700 Subject: [PATCH 13/31] install scripts --- .github/workflows/python-ci.yml | 2 +- README.rst | 11 +- poetry.lock | 164 +++++++++++++++++- pyproject.toml | 15 +- scripts/__init__.py | 0 ...sociate_ensemble => associate_ensemble.py} | 4 +- scripts/copyproddb.py | 3 +- ...generate_manifest => generate_manifest.py} | 4 +- scripts/{index_netcdf => index_netcdf.py} | 6 +- scripts/{list => list.py} | 3 +- scripts/{list-csv => list_csv.py} | 4 +- scripts/mktestdb.py | 3 +- scripts/nc-copy-modify.py | 1 - ...wms_configurator => ncwms_configurator.py} | 4 +- 14 files changed, 200 insertions(+), 24 deletions(-) create mode 100644 scripts/__init__.py rename scripts/{associate_ensemble => associate_ensemble.py} (96%) rename scripts/{generate_manifest => generate_manifest.py} (95%) rename scripts/{index_netcdf => index_netcdf.py} (82%) rename scripts/{list => list.py} (98%) rename scripts/{list-csv => list_csv.py} (93%) rename scripts/{ncwms_configurator => ncwms_configurator.py} (96%) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index d99f1eb..3e636fb 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -5,7 +5,7 @@ on: push jobs: test: - runs-on: ubuntu-22.04 + runs-on: ubuntu-latest strategy: matrix: python-version: diff --git a/README.rst b/README.rst index a9cc132..f544ea8 100644 --- a/README.rst +++ b/README.rst @@ -48,7 +48,7 @@ If you wish to install ``modelmeta`` manually, follow the steps below. #. Create a virtual environment:: $ cd modelmeta - $ pipenv install # --dev for development packages + $ poetry install # --with=test for development and testing Scripts to populate a PCIC modelmeta database @@ -76,11 +76,11 @@ Making files accessible to PCIC projects with associate_ensemble Once files have been indexed into the database, they need to be added to individual ensembles; each ensemble is associated with a particular project or website and contains all data files needed to support the functioning of that component. In most cases, a file will be added to more than one ensemble:: - associate_ensemble -n ensemble_name -v 1 -d postgresql://username:password@monsoon.pcic.uvic.ca/database /path/to/files/*.nc + associate_ensemble -n ensemble_name -v 1 -d postgresql://username:password@db.pcic.uvic.ca/database /path/to/files/*.nc **Available ensembles, or where should I put this data anyway?** -Most ensembles represent groupings of related files that users can interact with (view maps, download data, create graphs, etc) using a specific PCIC tool. Plan2adapt, the data portal, and PCEX all use ensembles in this way. +Most ensembles represent groupings of related files that users can interact with (view maps, download data, create graphs, etc) using a specific PCIC tool. Plan2adapt, the data portal, SCIP, and PCEX all use ensembles in this way. Plan2adapt uses a single ensemble which represents a list of all the files a user can view. The name of this ensemble is set when plan2adapt is deployed, as the environment variable ``REACT_APP_ENSEMBLE_NAME``. You can see the environment variables for a docker container running plan2adapt with ``docker exec container_name env``. @@ -88,13 +88,14 @@ The data portal uses a separate ensemble for each portal, which represents a lis PCEX is flexible about which ensembles it uses. A PCEX URL encodes both a UI and an ensemble which specifies which data is to be viewed with that UI. In theory you can look at any ensemble with any UI, but in practice, UIs make assumptions about the type of data available and most combinations won't work. In most cases, users access the various PCEX UIs pages via the `link bar at the top of the page `_. The ``navSubpath`` variable has the UI before the slash and the ensemble after it. PCEX UIs that display hydrological data for a watershed also have an additional ensemble that contains files that describe the geography of the watershed; this data cannot be directly viewed by the user but is required for some calculations. A list of these geographic ensembles can be `found `_ in ``getWatershedGeographyName()``. -There are also three special ensembles used by PCIC internal tools, not web portals. +SCIP is currently hardcoded to use an ensemble named "scip_fraser_bccoast". + +There are also two special ensembles used by PCIC internal tools, not web portals. * The ``all_files`` ensemble in the ``ce_meta_12f290b63791`` contains every file in the database, with the exception of time-invariant files. It is used with various scripts that `test `_ new functionality across all files. * The ``p2a_rules`` ensemble in the ``ce_meta_12f290b63791`` database contains all the information needed by plan2adapt's rules engine; it is used by the `scripts `_ which pre-generate rules engine results for plan2adapt, which are too slow to process in real time. -* The ``downscaled_canada`` ensemble in the ``pcic_meta`` database contains all datafiles for which map images can be generated for the portal website. It is used by `the ncWMS proxy `_ to generate map images for the data portal. When you add new files to this ensemble, you will need to reboot the ncWMS proxy to load the new files, or their maps will not be available. Deleting files from the databases --------------------------------- diff --git a/poetry.lock b/poetry.lock index b32a8c5..524cfe1 100644 --- a/poetry.lock +++ b/poetry.lock @@ -240,6 +240,152 @@ files = [ {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, ] +[[package]] +name = "lxml" +version = "5.4.0" +description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." +optional = false +python-versions = ">=3.6" +groups = ["test"] +files = [ + {file = "lxml-5.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e7bc6df34d42322c5289e37e9971d6ed114e3776b45fa879f734bded9d1fea9c"}, + {file = "lxml-5.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6854f8bd8a1536f8a1d9a3655e6354faa6406621cf857dc27b681b69860645c7"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:696ea9e87442467819ac22394ca36cb3d01848dad1be6fac3fb612d3bd5a12cf"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6ef80aeac414f33c24b3815ecd560cee272786c3adfa5f31316d8b349bfade28"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b9c2754cef6963f3408ab381ea55f47dabc6f78f4b8ebb0f0b25cf1ac1f7609"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7a62cc23d754bb449d63ff35334acc9f5c02e6dae830d78dab4dd12b78a524f4"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8f82125bc7203c5ae8633a7d5d20bcfdff0ba33e436e4ab0abc026a53a8960b7"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_28_aarch64.whl", hash = "sha256:b67319b4aef1a6c56576ff544b67a2a6fbd7eaee485b241cabf53115e8908b8f"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_28_ppc64le.whl", hash = "sha256:a8ef956fce64c8551221f395ba21d0724fed6b9b6242ca4f2f7beb4ce2f41997"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_28_s390x.whl", hash = "sha256:0a01ce7d8479dce84fc03324e3b0c9c90b1ece9a9bb6a1b6c9025e7e4520e78c"}, + {file = "lxml-5.4.0-cp310-cp310-manylinux_2_28_x86_64.whl", hash = "sha256:91505d3ddebf268bb1588eb0f63821f738d20e1e7f05d3c647a5ca900288760b"}, + {file = "lxml-5.4.0-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:a3bcdde35d82ff385f4ede021df801b5c4a5bcdfb61ea87caabcebfc4945dc1b"}, + {file = "lxml-5.4.0-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:aea7c06667b987787c7d1f5e1dfcd70419b711cdb47d6b4bb4ad4b76777a0563"}, + {file = "lxml-5.4.0-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:a7fb111eef4d05909b82152721a59c1b14d0f365e2be4c742a473c5d7372f4f5"}, + {file = "lxml-5.4.0-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:43d549b876ce64aa18b2328faff70f5877f8c6dede415f80a2f799d31644d776"}, + {file = "lxml-5.4.0-cp310-cp310-win32.whl", hash = "sha256:75133890e40d229d6c5837b0312abbe5bac1c342452cf0e12523477cd3aa21e7"}, + {file = "lxml-5.4.0-cp310-cp310-win_amd64.whl", hash = "sha256:de5b4e1088523e2b6f730d0509a9a813355b7f5659d70eb4f319c76beea2e250"}, + {file = "lxml-5.4.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:98a3912194c079ef37e716ed228ae0dcb960992100461b704aea4e93af6b0bb9"}, + {file = "lxml-5.4.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:0ea0252b51d296a75f6118ed0d8696888e7403408ad42345d7dfd0d1e93309a7"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b92b69441d1bd39f4940f9eadfa417a25862242ca2c396b406f9272ef09cdcaa"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:20e16c08254b9b6466526bc1828d9370ee6c0d60a4b64836bc3ac2917d1e16df"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7605c1c32c3d6e8c990dd28a0970a3cbbf1429d5b92279e37fda05fb0c92190e"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:ecf4c4b83f1ab3d5a7ace10bafcb6f11df6156857a3c418244cef41ca9fa3e44"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0cef4feae82709eed352cd7e97ae062ef6ae9c7b5dbe3663f104cd2c0e8d94ba"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_28_aarch64.whl", hash = "sha256:df53330a3bff250f10472ce96a9af28628ff1f4efc51ccba351a8820bca2a8ba"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_28_ppc64le.whl", hash = "sha256:aefe1a7cb852fa61150fcb21a8c8fcea7b58c4cb11fbe59c97a0a4b31cae3c8c"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_28_s390x.whl", hash = "sha256:ef5a7178fcc73b7d8c07229e89f8eb45b2908a9238eb90dcfc46571ccf0383b8"}, + {file = "lxml-5.4.0-cp311-cp311-manylinux_2_28_x86_64.whl", hash = "sha256:d2ed1b3cb9ff1c10e6e8b00941bb2e5bb568b307bfc6b17dffbbe8be5eecba86"}, + {file = "lxml-5.4.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:72ac9762a9f8ce74c9eed4a4e74306f2f18613a6b71fa065495a67ac227b3056"}, + {file = "lxml-5.4.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f5cb182f6396706dc6cc1896dd02b1c889d644c081b0cdec38747573db88a7d7"}, + {file = "lxml-5.4.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:3a3178b4873df8ef9457a4875703488eb1622632a9cee6d76464b60e90adbfcd"}, + {file = "lxml-5.4.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:e094ec83694b59d263802ed03a8384594fcce477ce484b0cbcd0008a211ca751"}, + {file = "lxml-5.4.0-cp311-cp311-win32.whl", hash = "sha256:4329422de653cdb2b72afa39b0aa04252fca9071550044904b2e7036d9d97fe4"}, + {file = "lxml-5.4.0-cp311-cp311-win_amd64.whl", hash = "sha256:fd3be6481ef54b8cfd0e1e953323b7aa9d9789b94842d0e5b142ef4bb7999539"}, + {file = "lxml-5.4.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:b5aff6f3e818e6bdbbb38e5967520f174b18f539c2b9de867b1e7fde6f8d95a4"}, + {file = "lxml-5.4.0-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:942a5d73f739ad7c452bf739a62a0f83e2578afd6b8e5406308731f4ce78b16d"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:460508a4b07364d6abf53acaa0a90b6d370fafde5693ef37602566613a9b0779"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:529024ab3a505fed78fe3cc5ddc079464e709f6c892733e3f5842007cec8ac6e"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ca56ebc2c474e8f3d5761debfd9283b8b18c76c4fc0967b74aeafba1f5647f9"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a81e1196f0a5b4167a8dafe3a66aa67c4addac1b22dc47947abd5d5c7a3f24b5"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:00b8686694423ddae324cf614e1b9659c2edb754de617703c3d29ff568448df5"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_28_aarch64.whl", hash = "sha256:c5681160758d3f6ac5b4fea370495c48aac0989d6a0f01bb9a72ad8ef5ab75c4"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_28_ppc64le.whl", hash = "sha256:2dc191e60425ad70e75a68c9fd90ab284df64d9cd410ba8d2b641c0c45bc006e"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_28_s390x.whl", hash = "sha256:67f779374c6b9753ae0a0195a892a1c234ce8416e4448fe1e9f34746482070a7"}, + {file = "lxml-5.4.0-cp312-cp312-manylinux_2_28_x86_64.whl", hash = "sha256:79d5bfa9c1b455336f52343130b2067164040604e41f6dc4d8313867ed540079"}, + {file = "lxml-5.4.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3d3c30ba1c9b48c68489dc1829a6eede9873f52edca1dda900066542528d6b20"}, + {file = "lxml-5.4.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:1af80c6316ae68aded77e91cd9d80648f7dd40406cef73df841aa3c36f6907c8"}, + {file = "lxml-5.4.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:4d885698f5019abe0de3d352caf9466d5de2baded00a06ef3f1216c1a58ae78f"}, + {file = "lxml-5.4.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:aea53d51859b6c64e7c51d522c03cc2c48b9b5d6172126854cc7f01aa11f52bc"}, + {file = "lxml-5.4.0-cp312-cp312-win32.whl", hash = "sha256:d90b729fd2732df28130c064aac9bb8aff14ba20baa4aee7bd0795ff1187545f"}, + {file = "lxml-5.4.0-cp312-cp312-win_amd64.whl", hash = "sha256:1dc4ca99e89c335a7ed47d38964abcb36c5910790f9bd106f2a8fa2ee0b909d2"}, + {file = "lxml-5.4.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:773e27b62920199c6197130632c18fb7ead3257fce1ffb7d286912e56ddb79e0"}, + {file = "lxml-5.4.0-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:ce9c671845de9699904b1e9df95acfe8dfc183f2310f163cdaa91a3535af95de"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:9454b8d8200ec99a224df8854786262b1bd6461f4280064c807303c642c05e76"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cccd007d5c95279e529c146d095f1d39ac05139de26c098166c4beb9374b0f4d"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0fce1294a0497edb034cb416ad3e77ecc89b313cff7adbee5334e4dc0d11f422"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:24974f774f3a78ac12b95e3a20ef0931795ff04dbb16db81a90c37f589819551"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:497cab4d8254c2a90bf988f162ace2ddbfdd806fce3bda3f581b9d24c852e03c"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_28_aarch64.whl", hash = "sha256:e794f698ae4c5084414efea0f5cc9f4ac562ec02d66e1484ff822ef97c2cadff"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_28_ppc64le.whl", hash = "sha256:2c62891b1ea3094bb12097822b3d44b93fc6c325f2043c4d2736a8ff09e65f60"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_28_s390x.whl", hash = "sha256:142accb3e4d1edae4b392bd165a9abdee8a3c432a2cca193df995bc3886249c8"}, + {file = "lxml-5.4.0-cp313-cp313-manylinux_2_28_x86_64.whl", hash = "sha256:1a42b3a19346e5601d1b8296ff6ef3d76038058f311902edd574461e9c036982"}, + {file = "lxml-5.4.0-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:4291d3c409a17febf817259cb37bc62cb7eb398bcc95c1356947e2871911ae61"}, + {file = "lxml-5.4.0-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:4f5322cf38fe0e21c2d73901abf68e6329dc02a4994e483adbcf92b568a09a54"}, + {file = "lxml-5.4.0-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:0be91891bdb06ebe65122aa6bf3fc94489960cf7e03033c6f83a90863b23c58b"}, + {file = "lxml-5.4.0-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:15a665ad90054a3d4f397bc40f73948d48e36e4c09f9bcffc7d90c87410e478a"}, + {file = "lxml-5.4.0-cp313-cp313-win32.whl", hash = "sha256:d5663bc1b471c79f5c833cffbc9b87d7bf13f87e055a5c86c363ccd2348d7e82"}, + {file = "lxml-5.4.0-cp313-cp313-win_amd64.whl", hash = "sha256:bcb7a1096b4b6b24ce1ac24d4942ad98f983cd3810f9711bcd0293f43a9d8b9f"}, + {file = "lxml-5.4.0-cp36-cp36m-macosx_10_9_x86_64.whl", hash = "sha256:7be701c24e7f843e6788353c055d806e8bd8466b52907bafe5d13ec6a6dbaecd"}, + {file = "lxml-5.4.0-cp36-cp36m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb54f7c6bafaa808f27166569b1511fc42701a7713858dddc08afdde9746849e"}, + {file = "lxml-5.4.0-cp36-cp36m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:97dac543661e84a284502e0cf8a67b5c711b0ad5fb661d1bd505c02f8cf716d7"}, + {file = "lxml-5.4.0-cp36-cp36m-manylinux_2_28_x86_64.whl", hash = "sha256:c70e93fba207106cb16bf852e421c37bbded92acd5964390aad07cb50d60f5cf"}, + {file = "lxml-5.4.0-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:9c886b481aefdf818ad44846145f6eaf373a20d200b5ce1a5c8e1bc2d8745410"}, + {file = "lxml-5.4.0-cp36-cp36m-musllinux_1_2_x86_64.whl", hash = "sha256:fa0e294046de09acd6146be0ed6727d1f42ded4ce3ea1e9a19c11b6774eea27c"}, + {file = "lxml-5.4.0-cp36-cp36m-win32.whl", hash = "sha256:61c7bbf432f09ee44b1ccaa24896d21075e533cd01477966a5ff5a71d88b2f56"}, + {file = "lxml-5.4.0-cp36-cp36m-win_amd64.whl", hash = "sha256:7ce1a171ec325192c6a636b64c94418e71a1964f56d002cc28122fceff0b6121"}, + {file = "lxml-5.4.0-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:795f61bcaf8770e1b37eec24edf9771b307df3af74d1d6f27d812e15a9ff3872"}, + {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:29f451a4b614a7b5b6c2e043d7b64a15bd8304d7e767055e8ab68387a8cacf4e"}, + {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4aa412a82e460571fad592d0f93ce9935a20090029ba08eca05c614f99b0cc92"}, + {file = "lxml-5.4.0-cp37-cp37m-manylinux_2_28_x86_64.whl", hash = "sha256:c5d32f5284012deaccd37da1e2cd42f081feaa76981f0eaa474351b68df813c5"}, + {file = "lxml-5.4.0-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:31e63621e073e04697c1b2d23fcb89991790eef370ec37ce4d5d469f40924ed6"}, + {file = "lxml-5.4.0-cp37-cp37m-win32.whl", hash = "sha256:be2ba4c3c5b7900246a8f866580700ef0d538f2ca32535e991027bdaba944063"}, + {file = "lxml-5.4.0-cp37-cp37m-win_amd64.whl", hash = "sha256:09846782b1ef650b321484ad429217f5154da4d6e786636c38e434fa32e94e49"}, + {file = "lxml-5.4.0-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:eaf24066ad0b30917186420d51e2e3edf4b0e2ea68d8cd885b14dc8afdcf6556"}, + {file = "lxml-5.4.0-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:2b31a3a77501d86d8ade128abb01082724c0dfd9524f542f2f07d693c9f1175f"}, + {file = "lxml-5.4.0-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0e108352e203c7afd0eb91d782582f00a0b16a948d204d4dec8565024fafeea5"}, + {file = "lxml-5.4.0-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a11a96c3b3f7551c8a8109aa65e8594e551d5a84c76bf950da33d0fb6dfafab7"}, + {file = "lxml-5.4.0-cp38-cp38-manylinux_2_28_aarch64.whl", hash = "sha256:ca755eebf0d9e62d6cb013f1261e510317a41bf4650f22963474a663fdfe02aa"}, + {file = "lxml-5.4.0-cp38-cp38-manylinux_2_28_x86_64.whl", hash = "sha256:4cd915c0fb1bed47b5e6d6edd424ac25856252f09120e3e8ba5154b6b921860e"}, + {file = "lxml-5.4.0-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:226046e386556a45ebc787871d6d2467b32c37ce76c2680f5c608e25823ffc84"}, + {file = "lxml-5.4.0-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:b108134b9667bcd71236c5a02aad5ddd073e372fb5d48ea74853e009fe38acb6"}, + {file = "lxml-5.4.0-cp38-cp38-win32.whl", hash = "sha256:1320091caa89805df7dcb9e908add28166113dcd062590668514dbd510798c88"}, + {file = "lxml-5.4.0-cp38-cp38-win_amd64.whl", hash = "sha256:073eb6dcdf1f587d9b88c8c93528b57eccda40209cf9be549d469b942b41d70b"}, + {file = "lxml-5.4.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:bda3ea44c39eb74e2488297bb39d47186ed01342f0022c8ff407c250ac3f498e"}, + {file = "lxml-5.4.0-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:9ceaf423b50ecfc23ca00b7f50b64baba85fb3fb91c53e2c9d00bc86150c7e40"}, + {file = "lxml-5.4.0-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:664cdc733bc87449fe781dbb1f309090966c11cc0c0cd7b84af956a02a8a4729"}, + {file = "lxml-5.4.0-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:67ed8a40665b84d161bae3181aa2763beea3747f748bca5874b4af4d75998f87"}, + {file = "lxml-5.4.0-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9b4a3bd174cc9cdaa1afbc4620c049038b441d6ba07629d89a83b408e54c35cd"}, + {file = "lxml-5.4.0-cp39-cp39-manylinux_2_28_aarch64.whl", hash = "sha256:b0989737a3ba6cf2a16efb857fb0dfa20bc5c542737fddb6d893fde48be45433"}, + {file = "lxml-5.4.0-cp39-cp39-manylinux_2_28_x86_64.whl", hash = "sha256:dc0af80267edc68adf85f2a5d9be1cdf062f973db6790c1d065e45025fa26140"}, + {file = "lxml-5.4.0-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:639978bccb04c42677db43c79bdaa23785dc7f9b83bfd87570da8207872f1ce5"}, + {file = "lxml-5.4.0-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:5a99d86351f9c15e4a901fc56404b485b1462039db59288b203f8c629260a142"}, + {file = "lxml-5.4.0-cp39-cp39-win32.whl", hash = "sha256:3e6d5557989cdc3ebb5302bbdc42b439733a841891762ded9514e74f60319ad6"}, + {file = "lxml-5.4.0-cp39-cp39-win_amd64.whl", hash = "sha256:a8c9b7f16b63e65bbba889acb436a1034a82d34fa09752d754f88d708eca80e1"}, + {file = "lxml-5.4.0-pp310-pypy310_pp73-macosx_10_15_x86_64.whl", hash = "sha256:1b717b00a71b901b4667226bba282dd462c42ccf618ade12f9ba3674e1fabc55"}, + {file = "lxml-5.4.0-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:27a9ded0f0b52098ff89dd4c418325b987feed2ea5cc86e8860b0f844285d740"}, + {file = "lxml-5.4.0-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4b7ce10634113651d6f383aa712a194179dcd496bd8c41e191cec2099fa09de5"}, + {file = "lxml-5.4.0-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:53370c26500d22b45182f98847243efb518d268374a9570409d2e2276232fd37"}, + {file = "lxml-5.4.0-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:c6364038c519dffdbe07e3cf42e6a7f8b90c275d4d1617a69bb59734c1a2d571"}, + {file = "lxml-5.4.0-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:b12cb6527599808ada9eb2cd6e0e7d3d8f13fe7bbb01c6311255a15ded4c7ab4"}, + {file = "lxml-5.4.0-pp37-pypy37_pp73-macosx_10_9_x86_64.whl", hash = "sha256:5f11a1526ebd0dee85e7b1e39e39a0cc0d9d03fb527f56d8457f6df48a10dc0c"}, + {file = "lxml-5.4.0-pp37-pypy37_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:48b4afaf38bf79109bb060d9016fad014a9a48fb244e11b94f74ae366a64d252"}, + {file = "lxml-5.4.0-pp37-pypy37_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de6f6bb8a7840c7bf216fb83eec4e2f79f7325eca8858167b68708b929ab2172"}, + {file = "lxml-5.4.0-pp37-pypy37_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:5cca36a194a4eb4e2ed6be36923d3cffd03dcdf477515dea687185506583d4c9"}, + {file = "lxml-5.4.0-pp37-pypy37_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:b7c86884ad23d61b025989d99bfdd92a7351de956e01c61307cb87035960bcb1"}, + {file = "lxml-5.4.0-pp37-pypy37_pp73-win_amd64.whl", hash = "sha256:53d9469ab5460402c19553b56c3648746774ecd0681b1b27ea74d5d8a3ef5590"}, + {file = "lxml-5.4.0-pp38-pypy38_pp73-macosx_10_9_x86_64.whl", hash = "sha256:56dbdbab0551532bb26c19c914848d7251d73edb507c3079d6805fa8bba5b706"}, + {file = "lxml-5.4.0-pp38-pypy38_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:14479c2ad1cb08b62bb941ba8e0e05938524ee3c3114644df905d2331c76cd57"}, + {file = "lxml-5.4.0-pp38-pypy38_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:32697d2ea994e0db19c1df9e40275ffe84973e4232b5c274f47e7c1ec9763cdd"}, + {file = "lxml-5.4.0-pp38-pypy38_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:24f6df5f24fc3385f622c0c9d63fe34604893bc1a5bdbb2dbf5870f85f9a404a"}, + {file = "lxml-5.4.0-pp38-pypy38_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:151d6c40bc9db11e960619d2bf2ec5829f0aaffb10b41dcf6ad2ce0f3c0b2325"}, + {file = "lxml-5.4.0-pp38-pypy38_pp73-win_amd64.whl", hash = "sha256:4025bf2884ac4370a3243c5aa8d66d3cb9e15d3ddd0af2d796eccc5f0244390e"}, + {file = "lxml-5.4.0-pp39-pypy39_pp73-macosx_10_15_x86_64.whl", hash = "sha256:9459e6892f59ecea2e2584ee1058f5d8f629446eab52ba2305ae13a32a059530"}, + {file = "lxml-5.4.0-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:47fb24cc0f052f0576ea382872b3fc7e1f7e3028e53299ea751839418ade92a6"}, + {file = "lxml-5.4.0-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:50441c9de951a153c698b9b99992e806b71c1f36d14b154592580ff4a9d0d877"}, + {file = "lxml-5.4.0-pp39-pypy39_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:ab339536aa798b1e17750733663d272038bf28069761d5be57cb4a9b0137b4f8"}, + {file = "lxml-5.4.0-pp39-pypy39_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:9776af1aad5a4b4a1317242ee2bea51da54b2a7b7b48674be736d463c999f37d"}, + {file = "lxml-5.4.0-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:63e7968ff83da2eb6fdda967483a7a023aa497d85ad8f05c3ad9b1f2e8c84987"}, + {file = "lxml-5.4.0.tar.gz", hash = "sha256:d12832e1dbea4be280b22fd0ea7c9b87f0d8fc51ba06e92dc62d52f804f78ebd"}, +] + +[package.extras] +cssselect = ["cssselect (>=0.7)"] +html-clean = ["lxml_html_clean"] +html5 = ["html5lib"] +htmlsoup = ["BeautifulSoup4"] +source = ["Cython (>=3.0.11,<3.1.0)"] + [[package]] name = "mako" version = "1.3.10" @@ -771,6 +917,22 @@ test-all = ["Babel (>=1.3)", "Jinja2 (>=2.3)", "Pygments (>=1.2)", "arrow (>=0.3 timezone = ["python-dateutil"] url = ["furl (>=0.4.1)"] +[[package]] +name = "sqlparse" +version = "0.5.3" +description = "A non-validating SQL parser." +optional = false +python-versions = ">=3.8" +groups = ["test"] +files = [ + {file = "sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca"}, + {file = "sqlparse-0.5.3.tar.gz", hash = "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272"}, +] + +[package.extras] +dev = ["build", "hatch"] +doc = ["sphinx"] + [[package]] name = "testing-common-database" version = "2.0.3" @@ -863,4 +1025,4 @@ files = [ [metadata] lock-version = "2.1" python-versions = ">=3.10" -content-hash = "e6d34ce616a47c01ade1011bf30bf1b57b3b457330baf06585a1b2dc87edc513" +content-hash = "2a59e37de9be789f5102ab3d78e3518d3f44f472c62dabe5816f94147d045ab9" diff --git a/pyproject.toml b/pyproject.toml index d577aba..0d00317 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -33,8 +33,19 @@ pytest = "^8.3.5" testing-postgresql = "^1.3.0" alembic-verify = ">=0.1.4,<0.2.0" sqlalchemy-diff = ">=0.1.5,<0.2.0" - - +sqlparse = "^0.5.3" +lxml = "^5.4.0" + + +[tool.poetry.scripts] +copyproddb="scripts.copyproddb:copy" +mktestdb="scripts.mktestdb:make_test" +list="scripts.list:list" +list_csv="scripts.list_csv:list" +index_netcdf="scripts.index_netcdf:index" +associate_ensemble="scripts.associate_ensemble:associate" +ncwms_configurator="scripts.ncwms_configurator:configurator" +generate_manifest="scripts.generate_manifest:generate" [tool.poetry.dependencies] diff --git a/scripts/__init__.py b/scripts/__init__.py new file mode 100644 index 0000000..e69de29 diff --git a/scripts/associate_ensemble b/scripts/associate_ensemble.py similarity index 96% rename from scripts/associate_ensemble rename to scripts/associate_ensemble.py index e5c9991..3cdc07e 100644 --- a/scripts/associate_ensemble +++ b/scripts/associate_ensemble.py @@ -3,8 +3,8 @@ from mm_cataloguer.associate_ensemble import main - -if __name__ == '__main__': +def associate(): + #if __name__ == '__main__': parser = ArgumentParser(description='Associate an ensemble to datafiles') parser.add_argument( '-d', '--dsn', required=True, diff --git a/scripts/copyproddb.py b/scripts/copyproddb.py index 30d4272..bf9da7b 100644 --- a/scripts/copyproddb.py +++ b/scripts/copyproddb.py @@ -14,7 +14,8 @@ class GenericMapper(Base): __table__ = table return GenericMapper -if __name__ == '__main__': +def copy(): + #if __name__ == '__main__': parser = ArgumentParser() parser.add_argument("-d", "--dsn", help="Source database DSN from which to read") parser.add_argument("-o", "--outdsn", help="Destination database DSN. Default is output.sqlite in current directory") diff --git a/scripts/generate_manifest b/scripts/generate_manifest.py similarity index 95% rename from scripts/generate_manifest rename to scripts/generate_manifest.py index 2add9af..a8f100e 100644 --- a/scripts/generate_manifest +++ b/scripts/generate_manifest.py @@ -5,8 +5,8 @@ from mm_cataloguer.generate_manifest import generate_manifest - -if __name__ == '__main__': +def generate(): + #if __name__ == '__main__': parser = ArgumentParser( description='Generate manifest of files requested from database') parser.add_argument("-c", "--connection_string", help="DSN for modelmeta database") diff --git a/scripts/index_netcdf b/scripts/index_netcdf.py similarity index 82% rename from scripts/index_netcdf rename to scripts/index_netcdf.py index a0b37b0..c0e9e9b 100644 --- a/scripts/index_netcdf +++ b/scripts/index_netcdf.py @@ -3,12 +3,12 @@ from mm_cataloguer.index_netcdf import index_netcdf_files - -if __name__ == '__main__': +def index(): + # if __name__ == '__main__': parser = ArgumentParser( description='Index PCIC metadata standard compliant NetCDF files ' 'into modelmeta database') parser.add_argument("-d", "--dsn", help="DSN for metadata database") parser.add_argument('filenames', nargs='+', help='Files to process') args = parser.parse_args() - index_netcdf_files(args.filenames, args.dsn) \ No newline at end of file + index_netcdf_files(args.filenames, args.dsn) diff --git a/scripts/list b/scripts/list.py similarity index 98% rename from scripts/list rename to scripts/list.py index 6f6e3b5..af49a9d 100644 --- a/scripts/list +++ b/scripts/list.py @@ -29,7 +29,8 @@ strtobool, \ list_filepaths, list_dirpaths -if __name__ == '__main__': +def list(): + # if __name__ == '__main__': main_parser = ArgumentParser( description='Tools for listing and summarizing contents of a ' diff --git a/scripts/list-csv b/scripts/list_csv.py similarity index 93% rename from scripts/list-csv rename to scripts/list_csv.py index f8ec6a2..922256d 100644 --- a/scripts/list-csv +++ b/scripts/list_csv.py @@ -8,8 +8,8 @@ from mm_cataloguer.list_csv import main - -if __name__ == '__main__': +def list(): + # if __name__ == '__main__': parser = ArgumentParser( description='List contents of a modelmeta database into a CSV file. ' 'Filename is fixed: modelmeta.csv' diff --git a/scripts/mktestdb.py b/scripts/mktestdb.py index 966c709..8ab9672 100644 --- a/scripts/mktestdb.py +++ b/scripts/mktestdb.py @@ -7,7 +7,8 @@ from sqlalchemy.orm import sessionmaker from sqlalchemy.schema import MetaData -if __name__ == '__main__': +def make_test(): + # if __name__ == '__main__': parser = ArgumentParser() parser.add_argument("-d", "--dsn", help="Source database DSN from which to read") parser.add_argument("-e", "--ensemble", help="Ensemble to copy from the database") diff --git a/scripts/nc-copy-modify.py b/scripts/nc-copy-modify.py index 44bf1b9..3b81a63 100644 --- a/scripts/nc-copy-modify.py +++ b/scripts/nc-copy-modify.py @@ -76,7 +76,6 @@ def nc_copy(source_fp, dest_fp, time_dimension, time_indices, variables): else: dest_variable[:] = source_variable[:] - if __name__ == '__main__': parser = ArgumentParser( description='Copy a NetCDF file with some modifications, ' diff --git a/scripts/ncwms_configurator b/scripts/ncwms_configurator.py similarity index 96% rename from scripts/ncwms_configurator rename to scripts/ncwms_configurator.py index 918424b..db9880b 100644 --- a/scripts/ncwms_configurator +++ b/scripts/ncwms_configurator.py @@ -6,8 +6,8 @@ from ncwms_configurator import create, update - -if __name__ == '__main__': +def configurator(): + # if __name__ == '__main__': logging.basicConfig(stream=sys.stdout, level=logging.INFO) From 0326164e9e8c648e12aa0ae93eca43205b470957 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Mon, 5 May 2025 14:28:00 -0700 Subject: [PATCH 14/31] update away from resource_filename --- modelmeta/v1.py | 4 ++-- modelmeta/v2.py | 2 -- scripts/copyproddb.py | 1 - scripts/mktestdb.py | 1 - tests/conftest.py | 4 ++-- tests/mm_cataloguer/test_associate_ensemble.py | 18 +++++++++--------- tests/mm_cataloguer/test_index.py | 10 +++++----- tests/modelmeta/test_against_test_sqlite_db.py | 4 ++-- 8 files changed, 20 insertions(+), 24 deletions(-) diff --git a/modelmeta/v1.py b/modelmeta/v1.py index 8eaed9c..071c2d6 100644 --- a/modelmeta/v1.py +++ b/modelmeta/v1.py @@ -3,7 +3,7 @@ 'DataFileVariable', 'Level', 'LevelSet', 'QCFlag',\ 'test_dsn', 'test_session'] -from pkg_resources import resource_filename +from importlib.resources import files from sqlalchemy import Column, Integer, Float, String, DateTime, Boolean, ForeignKey, create_engine from sqlalchemy.ext.declarative import declarative_base @@ -195,7 +195,7 @@ class QCFlag(Base): # timestep = Column(DateTime) # time_set_id = Column(Integer, ForeignKey('time_sets.time_set_id')) -test_dsn = 'sqlite+pysqlite:///{0}'.format(resource_filename('modelmeta', 'data/mddb-v1.sqlite')) +test_dsn = 'sqlite+pysqlite:///{0}'.format((files('modelmeta') / 'data/mddb-v1.sqlite').resolve()) def test_session(): '''This creates a testing database session that can be used as a test fixture. diff --git a/modelmeta/v2.py b/modelmeta/v2.py index 5169082..8e2d620 100644 --- a/modelmeta/v2.py +++ b/modelmeta/v2.py @@ -28,8 +28,6 @@ SpatialRefSys '''.split() -from pkg_resources import resource_filename - from sqlalchemy import Column, Integer, Float, String, DateTime, Boolean, \ Enum, ForeignKey, Index, UniqueConstraint from sqlalchemy.ext.declarative import declarative_base diff --git a/scripts/copyproddb.py b/scripts/copyproddb.py index bf9da7b..49f184e 100644 --- a/scripts/copyproddb.py +++ b/scripts/copyproddb.py @@ -1,7 +1,6 @@ import sys import logging from argparse import ArgumentParser -from pkg_resources import resource_filename from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker diff --git a/scripts/mktestdb.py b/scripts/mktestdb.py index 8ab9672..a5f36f3 100644 --- a/scripts/mktestdb.py +++ b/scripts/mktestdb.py @@ -1,7 +1,6 @@ import sys import logging from argparse import ArgumentParser -from pkg_resources import resource_filename from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker diff --git a/tests/conftest.py b/tests/conftest.py index ec52477..7b40975 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -25,7 +25,7 @@ """ import sys import os -from pkg_resources import resource_filename +from importlib.resources import files import datetime import pytest @@ -343,7 +343,7 @@ def db_uri(test_dsn): def open_tiny_dataset(abbrev): filename = 'data/tiny_{}.nc'.format(abbrev) - return CFDataset(resource_filename('modelmeta', filename)) + return CFDataset((files("modelmeta") / filename).resolve()) # We parametrize these fixture so that every test that uses it is run for all diff --git a/tests/mm_cataloguer/test_associate_ensemble.py b/tests/mm_cataloguer/test_associate_ensemble.py index 0ad8a5e..d79987e 100644 --- a/tests/mm_cataloguer/test_associate_ensemble.py +++ b/tests/mm_cataloguer/test_associate_ensemble.py @@ -1,7 +1,7 @@ """Test functions for associating an ensemble to a file. """ import pytest -from pkg_resources import resource_filename +from importlib.resources import files from nchelpers import CFDataset @@ -34,7 +34,7 @@ def index_test_files(Session): 'data/tiny_hydromodel_gcm.nc', 'data/tiny_gcm_climo_monthly.nc', ] - filenames = [resource_filename('modelmeta', f) for f in test_files] + filenames = [(files("modelmeta") / f).resolve() for f in test_files] for filename in filenames: with CFDataset(filename) as cf: find_update_or_insert_cf_file(session, cf) @@ -155,10 +155,10 @@ def test_associate_ensemble_to_data_file__( # associate_ensemble_to_filepath -fp_gcm = resource_filename('modelmeta', 'data/tiny_gcm.nc') -fp_downscaled = resource_filename('modelmeta', 'data/tiny_downscaled.nc') -fp_hydromodel_gcm = resource_filename('modelmeta', 'data/tiny_hydromodel_gcm.nc') -fp_gcm_climo_monthly = resource_filename('modelmeta', 'data/tiny_gcm_climo_monthly.nc') +fp_gcm = (files('modelmeta') / 'data/tiny_gcm.nc').resolve() +fp_downscaled = (files('modelmeta') /'data/tiny_downscaled.nc').resolve() +fp_hydromodel_gcm = (files('modelmeta') / 'data/tiny_hydromodel_gcm.nc').resolve() +fp_gcm_climo_monthly = (files('modelmeta') / 'data/tiny_gcm_climo_monthly.nc').resolve() @pytest.mark.slow @pytest.mark.parametrize( @@ -201,13 +201,13 @@ def test_associate_ensemble_to_filepath__( # Associate associated_items = associate_ensemble_to_filepath( session, ensemble1.name, ensemble1.version, - regex_filepath, filepath, var_names + regex_filepath, str(filepath), var_names ) # Verify assert set( df.filename for df, _ in associated_items - ) == expected_filepaths + ) == set(str(ef) for ef in expected_filepaths) assert set( dfv.netcdf_variable_name @@ -228,7 +228,7 @@ def test_associate_ensemble_to_filepath__( 'data/tiny_gcm_climo_monthly.nc', ] fps = [ - [resource_filename('modelmeta', f) for f in files_to_associate[:number]] + [str((files('modelmeta') / f).resolve()) for f in files_to_associate[:number]] for number in [1,2,4] ] diff --git a/tests/mm_cataloguer/test_index.py b/tests/mm_cataloguer/test_index.py index b9518d0..9cfc16c 100644 --- a/tests/mm_cataloguer/test_index.py +++ b/tests/mm_cataloguer/test_index.py @@ -25,7 +25,7 @@ import os import datetime -from pkg_resources import resource_filename +from importlib.resources import files import pytest from netCDF4 import date2num, num2date, chartostring @@ -1163,7 +1163,7 @@ def test_index_netcdf_file( create_test_database(test_engine_fs) # Index file - filepath = resource_filename('modelmeta', rel_filepath) + filepath = (files("modelmeta") / rel_filepath).resolve() data_file_id = index_netcdf_file(filepath, test_session_factory_fs) # Check results @@ -1174,7 +1174,7 @@ def test_index_netcdf_file( .filter(DataFile.id == data_file_id) .one() ) - assert data_file.filename == filepath + assert data_file.filename == str(filepath) session.close() @@ -1190,7 +1190,7 @@ def test_index_netcdf_file_with_error( create_test_database(test_engine_fs) # Index file - filepath = resource_filename('modelmeta', rel_filepath) + filepath = str((files("modelmeta") / rel_filepath).resolve()) data_file_id = index_netcdf_file(filepath, test_session_factory_fs) # Check results @@ -1220,7 +1220,7 @@ def test_index_netcdf_files(test_dsn_fs, test_engine_fs): 'data/tiny_gcm_climo_yearly.nc', 'data/tiny_streamflow.nc', ] - filenames = [resource_filename('modelmeta', f) for f in test_files] + filenames = [(files("modelmeta") / f).resolve() for f in test_files] data_file_ids = index_netcdf_files(filenames, test_dsn_fs) # Check results diff --git a/tests/modelmeta/test_against_test_sqlite_db.py b/tests/modelmeta/test_against_test_sqlite_db.py index 068c8c4..d1e694f 100644 --- a/tests/modelmeta/test_against_test_sqlite_db.py +++ b/tests/modelmeta/test_against_test_sqlite_db.py @@ -1,4 +1,4 @@ -from pkg_resources import resource_filename +from importlib.resources import files import modelmeta @@ -8,7 +8,7 @@ @pytest.fixture def test_session(): - f = resource_filename('modelmeta', 'data/mddb-v2.sqlite') + f = (files("modelmeta") / "data/mddb-v2.sqlite").resolve() engine = create_engine('sqlite:///{0}'.format(f)) Session = sessionmaker(bind=engine) return Session() From e2cd70e5d01f1fe14204f11bda54923764af9d14 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Wed, 7 May 2025 13:14:11 -0700 Subject: [PATCH 15/31] upgrade from naive datetimes to aware ones --- .github/workflows/python-ci.yml | 2 +- mm_cataloguer/index_netcdf.py | 11 ++++++++--- modelmeta/v2.py | 2 +- tests/conftest.py | 2 +- tests/mm_cataloguer/test_index.py | 6 +++++- 5 files changed, 16 insertions(+), 7 deletions(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index 3e636fb..d99f1eb 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -5,7 +5,7 @@ on: push jobs: test: - runs-on: ubuntu-latest + runs-on: ubuntu-22.04 strategy: matrix: python-version: diff --git a/mm_cataloguer/index_netcdf.py b/mm_cataloguer/index_netcdf.py index d584bee..00e35b7 100644 --- a/mm_cataloguer/index_netcdf.py +++ b/mm_cataloguer/index_netcdf.py @@ -153,7 +153,12 @@ def mean_step_size(values): def seconds_since_epoch(t): """Convert a datetime to the number of seconds since the Unix epoch.""" - return (t-datetime.datetime(1970, 1, 1)).total_seconds() + # add a timezone, if one is missing + if t.tzinfo is None: + utc_t = t.replace(tzinfo=datetime.UTC) + else: + utc_t = t + return (utc_t-datetime.datetime(1970, 1, 1, tzinfo=datetime.UTC)).total_seconds() @memoize @@ -1124,7 +1129,7 @@ def insert_data_file(sesh, cf): # create.data.file.id filename=cf.filepath(converter=filepath_converter), first_1mib_md5sum=cf.first_MiB_md5sum, unique_id=cf.unique_id, - index_time=datetime.datetime.utcnow(), + index_time=datetime.datetime.now(datetime.UTC), run=run, timeset=timeset, x_dim_name=dim_names.get('X', None), @@ -1188,7 +1193,7 @@ def delete_data_file(sesh, existing_data_file): def update_data_file_index_time(sesh, data_file): """Update the index time recorded for data_file""" logger.info('Updating index time (only)') - data_file.index_time = datetime.datetime.utcnow() + data_file.index_time = datetime.datetime.now(datetime.UTC) return data_file diff --git a/modelmeta/v2.py b/modelmeta/v2.py index 8e2d620..743658b 100644 --- a/modelmeta/v2.py +++ b/modelmeta/v2.py @@ -30,7 +30,7 @@ from sqlalchemy import Column, Integer, Float, String, DateTime, Boolean, \ Enum, ForeignKey, Index, UniqueConstraint -from sqlalchemy.ext.declarative import declarative_base +from sqlalchemy.orm import declarative_base from sqlalchemy.ext.orderinglist import ordering_list from sqlalchemy.orm import relationship, backref, sessionmaker diff --git a/tests/conftest.py b/tests/conftest.py index 7b40975..7ebab56 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -81,7 +81,7 @@ def make_data_file(i, run=None, timeset=None): x_dim_name='lon', y_dim_name='lat', t_dim_name='time', - index_time=datetime.datetime.now(), + index_time=datetime.datetime.now(datetime.UTC), run=run, timeset=timeset, ) diff --git a/tests/mm_cataloguer/test_index.py b/tests/mm_cataloguer/test_index.py index 9cfc16c..527d961 100644 --- a/tests/mm_cataloguer/test_index.py +++ b/tests/mm_cataloguer/test_index.py @@ -142,11 +142,14 @@ def freeze_utcnow(*args): """ monkeypatch = args[0] fake_now = datetime.datetime(*args[1:]) + print("FAKE NOW", fake_now) class fake_datetime(datetime.datetime): @classmethod def utcnow(cls): return fake_now + def now(cls): + return fake_now monkeypatch.setattr(datetime, 'datetime', fake_datetime) return fake_now @@ -932,7 +935,8 @@ def test_insert_data_file( ): # Have to use a datetime with no hours, min, sec because apparently # SQLite loses precision - fake_now = freeze_utcnow(monkeypatch, 2000, 1, 2) + #fake_now = freeze_utcnow(monkeypatch, 2000, 1, 2) + fake_now = freeze_utcnow(monkeypatch, datetime.datetime.now(datetime.UTC).year, datetime.datetime.now(datetime.UTC).month, datetime.datetime.now(datetime.UTC).day) dim_names = tiny_any_dataset.axes_dim() data_file = check_insert( insert_data_file, test_session_with_empty_db, tiny_any_dataset, From 1a9a03747584f217f1df40e617c94e168f43f2b6 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Wed, 7 May 2025 17:30:12 -0700 Subject: [PATCH 16/31] Upgrade to PEP 621 --- .github/workflows/pypi-publish.yml | 11 +-- .github/workflows/python-ci.yml | 2 +- poetry.lock | 113 +++++++++++++++++------------ pyproject.toml | 61 ++++++++++------ setup.cfg | 3 - setup.py | 67 ----------------- 6 files changed, 110 insertions(+), 147 deletions(-) delete mode 100644 setup.cfg delete mode 100644 setup.py diff --git a/.github/workflows/pypi-publish.yml b/.github/workflows/pypi-publish.yml index e888ee2..a3738ff 100644 --- a/.github/workflows/pypi-publish.yml +++ b/.github/workflows/pypi-publish.yml @@ -16,14 +16,15 @@ jobs: uses: actions/setup-python@v2 with: python-version: '3.11' - - name: Install dependencies + - name: Install Poetry run: | - python -m pip install --upgrade pip - pip install setuptools wheel twine + curl -sSL https://install.python-poetry.org | python3 - - name: Build and publish env: TWINE_USERNAME: ${{ secrets.pcic_at_pypi_username }} TWINE_PASSWORD: ${{ secrets.pcic_at_pypi_password }} run: | - python setup.py sdist bdist_wheel - twine upload --repository-url https://pypi.pacificclimate.org/ --skip-existing -u $TWINE_USERNAME -p $TWINE_PASSWORD dist/* + poetry config repositories.pcic https://pypi.pacificclimate.org/ + poetry config http-basic.pcic $PCIC_PYPI_USERNAME $PCIC_PYPI_PASSWORD + poetry build + poetry publish -r pcic \ No newline at end of file diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index d99f1eb..dc1a0fe 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -32,7 +32,7 @@ jobs: - name: Install python dependencies run: | - poetry install --with=test + poetry install --extras test - name: Test with pytest (full) if: github.ref == 'refs/heads/master' diff --git a/poetry.lock b/poetry.lock index 524cfe1..04f5bb5 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,4 +1,4 @@ -# This file is automatically @generated by Poetry 2.1.2 and should not be changed by hand. +# This file is automatically @generated by Poetry 2.1.3 and should not be changed by hand. [[package]] name = "alembic" @@ -6,7 +6,7 @@ version = "1.15.2" description = "A database migration tool for SQLAlchemy." optional = false python-versions = ">=3.9" -groups = ["main", "test"] +groups = ["main"] files = [ {file = "alembic-1.15.2-py3-none-any.whl", hash = "sha256:2e76bd916d547f6900ec4bb5a90aeac1485d2c92536923d0b138c02b126edc53"}, {file = "alembic-1.15.2.tar.gz", hash = "sha256:1c72391bbdeffccfe317eefba686cb9a3c078005478885413b95c3b26c57a8a7"}, @@ -24,9 +24,10 @@ tz = ["tzdata"] name = "alembic-verify" version = "0.1.4" description = "A library to verify migrations and models are in sync." -optional = false +optional = true python-versions = "*" -groups = ["test"] +groups = ["main"] +markers = "extra == \"test\"" files = [ {file = "alembic-verify-0.1.4.tar.gz", hash = "sha256:cab4ae105d573851dbb30e9771944773da938ffbf687c4780d914dda23b363e5"}, {file = "alembic_verify-0.1.4-py2-none-any.whl", hash = "sha256:763c6013b3a7589dacde107ca44a4f34e5a072e5a9aa0675603e5bf417e6f2c6"}, @@ -45,9 +46,10 @@ docs = ["Sphinx (==1.3.1)"] name = "asn1crypto" version = "1.5.1" description = "Fast ASN.1 parser and serializer with definitions for private keys, public keys, certificates, CRL, OCSP, CMS, PKCS#3, PKCS#7, PKCS#8, PKCS#12, PKCS#5, X.509 and TSP" -optional = false +optional = true python-versions = "*" -groups = ["test"] +groups = ["main"] +markers = "extra == \"test\"" files = [ {file = "asn1crypto-1.5.1-py2.py3-none-any.whl", hash = "sha256:db4e40728b728508912cbb3d44f19ce188f218e9eba635821bb4b68564f8fd67"}, {file = "asn1crypto-1.5.1.tar.gz", hash = "sha256:13ae38502be632115abf8a24cbe5f4da52e3b5231990aff31123c805306ccb9c"}, @@ -133,10 +135,10 @@ numpy = [ name = "colorama" version = "0.4.6" description = "Cross-platform colored terminal text." -optional = false +optional = true python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" -groups = ["test"] -markers = "sys_platform == \"win32\"" +groups = ["main"] +markers = "extra == \"test\" and sys_platform == \"win32\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, @@ -146,10 +148,10 @@ files = [ name = "exceptiongroup" version = "1.2.2" description = "Backport of PEP 654 (exception groups)" -optional = false +optional = true python-versions = ">=3.7" -groups = ["test"] -markers = "python_version == \"3.10\"" +groups = ["main"] +markers = "extra == \"test\" and python_version == \"3.10\"" files = [ {file = "exceptiongroup-1.2.2-py3-none-any.whl", hash = "sha256:3111b9d131c238bec2f8f516e123e14ba243563fb135d3fe885990585aa7795b"}, {file = "exceptiongroup-1.2.2.tar.gz", hash = "sha256:47c2edf7c6738fafb49fd34290706d1a1a2f4d1c6df275526b62cbb4aa5393cc"}, @@ -164,7 +166,7 @@ version = "3.2.1" description = "Lightweight in-process concurrent programming" optional = false python-versions = ">=3.9" -groups = ["main", "test"] +groups = ["main"] markers = "python_version < \"3.14\" and (platform_machine == \"aarch64\" or platform_machine == \"ppc64le\" or platform_machine == \"x86_64\" or platform_machine == \"amd64\" or platform_machine == \"AMD64\" or platform_machine == \"win32\" or platform_machine == \"WIN32\")" files = [ {file = "greenlet-3.2.1-cp310-cp310-macosx_11_0_universal2.whl", hash = "sha256:777c1281aa7c786738683e302db0f55eb4b0077c20f1dc53db8852ffaea0a6b0"}, @@ -232,9 +234,10 @@ test = ["objgraph", "psutil"] name = "iniconfig" version = "2.1.0" description = "brain-dead simple config-ini parsing" -optional = false +optional = true python-versions = ">=3.8" -groups = ["test"] +groups = ["main"] +markers = "extra == \"test\"" files = [ {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, @@ -244,9 +247,10 @@ files = [ name = "lxml" version = "5.4.0" description = "Powerful and Pythonic XML processing library combining libxml2/libxslt with the ElementTree API." -optional = false +optional = true python-versions = ">=3.6" -groups = ["test"] +groups = ["main"] +markers = "extra == \"test\"" files = [ {file = "lxml-5.4.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:e7bc6df34d42322c5289e37e9971d6ed114e3776b45fa879f734bded9d1fea9c"}, {file = "lxml-5.4.0-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:6854f8bd8a1536f8a1d9a3655e6354faa6406621cf857dc27b681b69860645c7"}, @@ -392,7 +396,7 @@ version = "1.3.10" description = "A super-fast templating language that borrows the best ideas from the existing templating languages." optional = false python-versions = ">=3.8" -groups = ["main", "test"] +groups = ["main"] files = [ {file = "mako-1.3.10-py3-none-any.whl", hash = "sha256:baef24a52fc4fc514a0887ac600f9f1cff3d82c61d4d700a1fa84d597b88db59"}, {file = "mako-1.3.10.tar.gz", hash = "sha256:99579a6f39583fa7e5630a28c3c1f440e4e97a414b80372649c0ce338da2ea28"}, @@ -412,7 +416,7 @@ version = "3.0.2" description = "Safely add untrusted strings to HTML/XML markup." optional = false python-versions = ">=3.9" -groups = ["main", "test"] +groups = ["main"] files = [ {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:7e94c425039cde14257288fd61dcfb01963e658efbc0ff54f5306b06054700f8"}, {file = "MarkupSafe-3.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:9e2d922824181480953426608b81967de705c3cef4d1af983af849d7bd619158"}, @@ -616,9 +620,10 @@ files = [ name = "packaging" version = "25.0" description = "Core utilities for Python packages" -optional = false +optional = true python-versions = ">=3.8" -groups = ["test"] +groups = ["main"] +markers = "extra == \"test\"" files = [ {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, @@ -628,9 +633,10 @@ files = [ name = "pg8000" version = "1.31.2" description = "PostgreSQL interface library" -optional = false +optional = true python-versions = ">=3.8" -groups = ["test"] +groups = ["main"] +markers = "extra == \"test\"" files = [ {file = "pg8000-1.31.2-py3-none-any.whl", hash = "sha256:436c771ede71af4d4c22ba867a30add0bc5c942d7ab27fadbb6934a487ecc8f6"}, {file = "pg8000-1.31.2.tar.gz", hash = "sha256:1ea46cf09d8eca07fe7eaadefd7951e37bee7fabe675df164f1a572ffb300876"}, @@ -644,9 +650,10 @@ scramp = ">=1.4.5" name = "pluggy" version = "1.5.0" description = "plugin and hook calling mechanisms for python" -optional = false +optional = true python-versions = ">=3.8" -groups = ["test"] +groups = ["main"] +markers = "extra == \"test\"" files = [ {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, @@ -691,9 +698,10 @@ files = [ name = "pytest" version = "8.3.5" description = "pytest: simple powerful testing with Python" -optional = false +optional = true python-versions = ">=3.8" -groups = ["test"] +groups = ["main"] +markers = "extra == \"test\"" files = [ {file = "pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820"}, {file = "pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"}, @@ -716,7 +724,7 @@ version = "2.9.0.post0" description = "Extensions to the standard Python datetime module" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main", "test"] +groups = ["main"] files = [ {file = "python-dateutil-2.9.0.post0.tar.gz", hash = "sha256:37dd54208da7e1cd875388217d5e00ebd4179249f90fb72437e91a35459a0ad3"}, {file = "python_dateutil-2.9.0.post0-py2.py3-none-any.whl", hash = "sha256:a8b2bc7bffae282281c8140a97d3aa9c14da0b136dfe83f850eea9a5f7470427"}, @@ -729,9 +737,10 @@ six = ">=1.5" name = "scramp" version = "1.4.5" description = "An implementation of the SCRAM protocol." -optional = false +optional = true python-versions = ">=3.8" -groups = ["test"] +groups = ["main"] +markers = "extra == \"test\"" files = [ {file = "scramp-1.4.5-py3-none-any.whl", hash = "sha256:50e37c464fc67f37994e35bee4151e3d8f9320e9c204fca83a5d313c121bbbe7"}, {file = "scramp-1.4.5.tar.gz", hash = "sha256:be3fbe774ca577a7a658117dca014e5d254d158cecae3dd60332dfe33ce6d78e"}, @@ -767,7 +776,7 @@ version = "1.17.0" description = "Python 2 and 3 compatibility utilities" optional = false python-versions = "!=3.0.*,!=3.1.*,!=3.2.*,>=2.7" -groups = ["main", "test"] +groups = ["main"] files = [ {file = "six-1.17.0-py2.py3-none-any.whl", hash = "sha256:4721f391ed90541fddacab5acf947aa0d3dc7d27b2e1e8eda2be8970586c3274"}, {file = "six-1.17.0.tar.gz", hash = "sha256:ff70335d468e7eb6ec65b95b99d3a2836546063f63acc5171de367e834932a81"}, @@ -779,7 +788,7 @@ version = "2.0.40" description = "Database Abstraction Library" optional = false python-versions = ">=3.7" -groups = ["main", "test"] +groups = ["main"] files = [ {file = "SQLAlchemy-2.0.40-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:ae9597cab738e7cc823f04a704fb754a9249f0b6695a6aeb63b74055cd417a96"}, {file = "SQLAlchemy-2.0.40-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37a5c21ab099a83d669ebb251fddf8f5cee4d75ea40a5a1653d9c43d60e20867"}, @@ -873,9 +882,10 @@ sqlcipher = ["sqlcipher3_binary"] name = "sqlalchemy-diff" version = "0.1.5" description = "Compare two database schemas using sqlalchemy." -optional = false +optional = true python-versions = "*" -groups = ["test"] +groups = ["main"] +markers = "extra == \"test\"" files = [ {file = "sqlalchemy-diff-0.1.5.tar.gz", hash = "sha256:2a3d4de3cb7580876789a7da25040ae5b827c7a70ee4e733daef1ab68aad0e72"}, {file = "sqlalchemy_diff-0.1.5-py3-none-any.whl", hash = "sha256:8b618238de87e0062b025b0ff2cb4f9928ddddb64a5bb50bd407cd06b9543314"}, @@ -892,9 +902,10 @@ docs = ["sphinx (==1.4.1)"] name = "sqlalchemy-utils" version = "0.41.2" description = "Various utility functions for SQLAlchemy." -optional = false +optional = true python-versions = ">=3.7" -groups = ["test"] +groups = ["main"] +markers = "extra == \"test\"" files = [ {file = "SQLAlchemy-Utils-0.41.2.tar.gz", hash = "sha256:bc599c8c3b3319e53ce6c5c3c471120bd325d0071fb6f38a10e924e3d07b9990"}, {file = "SQLAlchemy_Utils-0.41.2-py3-none-any.whl", hash = "sha256:85cf3842da2bf060760f955f8467b87983fb2e30f1764fd0e24a48307dc8ec6e"}, @@ -921,9 +932,10 @@ url = ["furl (>=0.4.1)"] name = "sqlparse" version = "0.5.3" description = "A non-validating SQL parser." -optional = false +optional = true python-versions = ">=3.8" -groups = ["test"] +groups = ["main"] +markers = "extra == \"test\"" files = [ {file = "sqlparse-0.5.3-py3-none-any.whl", hash = "sha256:cf2196ed3418f3ba5de6af7e82c694a9fbdbfecccdfc72e281548517081f16ca"}, {file = "sqlparse-0.5.3.tar.gz", hash = "sha256:09f67787f56a0b16ecdbde1bfc7f5d9c3371ca683cfeaa8e6ff60b4807ec9272"}, @@ -937,9 +949,10 @@ doc = ["sphinx"] name = "testing-common-database" version = "2.0.3" description = "utilities for testing.* packages" -optional = false +optional = true python-versions = "*" -groups = ["test"] +groups = ["main"] +markers = "extra == \"test\"" files = [ {file = "testing.common.database-2.0.3-py2.py3-none-any.whl", hash = "sha256:e3ed492bf480a87f271f74c53b262caf5d85c8bc09989a8f534fa2283ec52492"}, {file = "testing.common.database-2.0.3.tar.gz", hash = "sha256:965d80b2985315325dc358c3061b174a712f4d4d5bf6a80b58b11f9a1dd86d73"}, @@ -952,9 +965,10 @@ testing = ["nose"] name = "testing-postgresql" version = "1.3.0" description = "automatically setups a postgresql instance in a temporary directory, and destroys it after testing" -optional = false +optional = true python-versions = "*" -groups = ["test"] +groups = ["main"] +markers = "extra == \"test\"" files = [ {file = "testing.postgresql-1.3.0-py2.py3-none-any.whl", hash = "sha256:1b41daeb98dfc8cd4a584bb91e8f5f4ab182993870f95257afe5f1ba6151a598"}, {file = "testing.postgresql-1.3.0.tar.gz", hash = "sha256:8e1a69760369a7a8ffe63a66b6d95a5cd82db2fb976e4a8f85ffd24fbfc447d8"}, @@ -971,10 +985,10 @@ testing = ["SQLAlchemy", "nose", "psycopg2"] name = "tomli" version = "2.2.1" description = "A lil' TOML parser" -optional = false +optional = true python-versions = ">=3.8" -groups = ["test"] -markers = "python_version == \"3.10\"" +groups = ["main"] +markers = "extra == \"test\" and python_version == \"3.10\"" files = [ {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, @@ -1016,13 +1030,16 @@ version = "4.13.2" description = "Backported and Experimental Type Hints for Python 3.8+" optional = false python-versions = ">=3.8" -groups = ["main", "test"] +groups = ["main"] files = [ {file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"}, {file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"}, ] +[extras] +test = ["alembic-verify", "lxml", "pytest", "sqlalchemy-diff", "sqlparse", "testing-postgresql"] + [metadata] lock-version = "2.1" -python-versions = ">=3.10" -content-hash = "2a59e37de9be789f5102ab3d78e3518d3f44f472c62dabe5816f94147d045ab9" +python-versions = ">=3.10,<4.0" +content-hash = "2b90a3f88381d059f0be08342970868851d49b79ef787e0399513dc1741139cd" diff --git a/pyproject.toml b/pyproject.toml index 0d00317..b9d97ae 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,12 @@ +[build-system] +requires = ["poetry-core>=2.0.0,<3.0.0"] +build-backend = "poetry.core.masonry.api" + [project] name = "modelmeta" version = "0.1.2" +requires-python = ">=3.10,<4.0" +readme = "README.rst" description = "An ORM representation of the model meta database" authors = [ {name = "James Hiebert", email = "hiebert@uvic.ca"}, @@ -9,18 +15,37 @@ authors = [ {name = "Lee Zeman", email = "lzeman@uvic.ca"}, {name = "David Bronaugh"} ] -requires-python = ">=3.10" +classifiers=[ + "Programming Language :: Python :: 3", + "Programming Language :: Python :: 3.10", + "Programming Language :: Python :: 3.11", + "Programming Language :: Python :: 3.12", +] +keywords = [ + "sql", + "database", + "climate" +] dependencies = [ - "setuptools (>=79.0.1,<80.0.0)", - "nchelpers (>=5.5.11,<6.0.0)", - "pycrs (>=1.0.2,<2.0.0)", - "alembic (>=1.15.2,<2.0.0)", - "psycopg2 (>=2.9.10,<3.0.0)", - "sqlalchemy (>=2.0.40,<3.0.0)", + "setuptools>=79.0.1,<80.0.0", + "pycrs>=1.0.2,<2.0.0", + "alembic>=1.15.2,<2.0.0", + "psycopg2>=2.9.10,<3.0.0", + "sqlalchemy>=2.0.40,<3.0.0", + "nchelpers>=5.5.11,<6.0.0", +] + + +[project.optional-dependencies] +test = [ + "pytest==8.3.5", + "testing-postgresql==1.3.0", + "alembic-verify>=0.1.4,<0.2.0", + "sqlalchemy-diff>=0.1.5,<0.2.0", + "sqlparse==0.5.3", + "lxml==5.4.0", ] -[tool.poetry] -packages = [{include = "modelmeta"}] [[tool.poetry.source]] name = "pcic" @@ -28,15 +53,6 @@ url = "https://pypi.pacificclimate.org/simple" priority = "supplemental" -[tool.poetry.group.test.dependencies] -pytest = "^8.3.5" -testing-postgresql = "^1.3.0" -alembic-verify = ">=0.1.4,<0.2.0" -sqlalchemy-diff = ">=0.1.5,<0.2.0" -sqlparse = "^0.5.3" -lxml = "^5.4.0" - - [tool.poetry.scripts] copyproddb="scripts.copyproddb:copy" mktestdb="scripts.mktestdb:make_test" @@ -48,8 +64,7 @@ ncwms_configurator="scripts.ncwms_configurator:configurator" generate_manifest="scripts.generate_manifest:generate" -[tool.poetry.dependencies] -nchelpers = {source = "pcic"} -[build-system] -requires = ["poetry-core>=2.0.0,<3.0.0"] -build-backend = "poetry.core.masonry.api" +[tool.pytest.ini_options] +markers = [ + "slow: marks tests that are slow (deselect with '-m \"not slow\"')", +] diff --git a/setup.cfg b/setup.cfg deleted file mode 100644 index 727d86d..0000000 --- a/setup.cfg +++ /dev/null @@ -1,3 +0,0 @@ -[pytest] -norecursedirs = tests/helpers -testpaths = tests \ No newline at end of file diff --git a/setup.py b/setup.py deleted file mode 100644 index cd2879c..0000000 --- a/setup.py +++ /dev/null @@ -1,67 +0,0 @@ -import string -from setuptools import setup - -__version__ = (1, 0, 1) - -setup( - name="modelmeta", - description="An ORM representation of the model metadata database", - keywords="sql database climate", - packages=['modelmeta', 'mm_cataloguer', 'ncwms_configurator'], - version='.'.join(str(d) for d in __version__), - url="http://www.pacificclimate.org/", - author="James Hiebert", - author_email="hiebert@uvic.ca", - zip_safe=False, - install_requires = ''' - sqlalchemy - alembic - psycopg2 - numpy - netCDF4 - nchelpers>=5.5.0 - python-dateutil - sqlparse - PyCRS - lxml - '''.split(), - package_data = { - 'modelmeta': ''' - data/mddb-v1.sqlite - data/mddb-v2.sqlite - data/bad_tiny_gcm.nc - data/tiny_gcm.nc - data/tiny_downscaled.nc - data/tiny_hydromodel_gcm.nc - data/tiny_gcm_climo_yearly.nc - data/tiny_gcm_climo_seasonal.nc - data/tiny_gcm_climo_monthly.nc - data/tiny_gridded_obs.nc - data/tiny_streamflow.nc - '''.split() - }, - include_package_data = True, - scripts = ''' - scripts/copyproddb.py - scripts/mktestdb.py - scripts/list - scripts/list-csv - scripts/index_netcdf - scripts/associate_ensemble - scripts/ncwms_configurator - scripts/generate_manifest - '''.split(), - classifiers=['Development Status :: 5 - Production/Stable', - 'Environment :: Console', - 'Intended Audience :: Developers', - 'Intended Audience :: Science/Research', - 'License :: OSI Approved :: GNU General Public License v3 (GPLv3)', - 'Operating System :: OS Independent', - 'Programming Language :: Python :: 3.10', - 'Programming Language :: Python :: 3.11', - 'Programming Language :: Python :: 3.12', - 'Topic :: Scientific/Engineering', - 'Topic :: Database', - 'Topic :: Software Development :: Libraries :: Python Modules' - ] -) From ff4e7605d297e219eb7787ef885348750392df96 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Thu, 8 May 2025 13:29:25 -0700 Subject: [PATCH 17/31] update to Ubuntu 24.04, script install with poethepoet --- .github/workflows/python-ci.yml | 4 +- Makefile | 19 +- README.md | 325 ++++++++++++++++++++++++++++++ README.rst | 10 +- poetry.lock | 103 +++++++++- pyproject.toml | 15 ++ tests/mm_cataloguer/test_index.py | 1 - 7 files changed, 455 insertions(+), 22 deletions(-) create mode 100644 README.md diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index dc1a0fe..fb367bd 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -5,7 +5,7 @@ on: push jobs: test: - runs-on: ubuntu-22.04 + runs-on: ubuntu-24.04 strategy: matrix: python-version: @@ -23,7 +23,7 @@ jobs: - name: Install system dependencies run: | sudo apt-get update - sudo apt-get install postgis postgresql-14 postgresql-client-14 libhdf5-serial-dev libnetcdf-dev libspatialite-dev wget + sudo apt-get install postgresql-16 postgresql-client-16 libhdf5-serial-dev libnetcdf-dev libspatialite-dev wget - name: Install poetry run: | diff --git a/Makefile b/Makefile index ee87dc2..22317b7 100644 --- a/Makefile +++ b/Makefile @@ -1,17 +1,16 @@ -all: install install-pipenv test +all: install install-poetry test install: - sudo apt-get install postgresql-14 \ - postgresql-client-14 \ + sudo apt-get install postgresql-16 \ + postgresql-client-16 \ libhdf5-serial-dev \ libnetcdf-dev \ libspatialite-dev \ - postgresql-14-postgis-3 + postgresql-16-postgis-3 -install-pipenv: - sudo apt-get install pipenv - pipenv install - pipenv install --dev +install-poetry: + pip install poetry + poetry install --extras test -test: install - pipenv run pytest -v +test: + poetry run pytest -v diff --git a/README.md b/README.md new file mode 100644 index 0000000..5ff26d0 --- /dev/null +++ b/README.md @@ -0,0 +1,325 @@ +# modelmeta + +[![image](https://github.com/pacificclimate/modelmeta/workflows/Python%20CI/badge.svg)](https://github.com/pacificclimate/modelmeta) + +[![image](https://github.com/pacificclimate/modelmeta/workflows/Pypi%20Publishing/badge.svg)](https://github.com/pacificclimate/modelmeta) + +[![Code Climate](https://codeclimate.com/github/pacificclimate/modelmeta/badges/gpa.svg)](https://codeclimate.com/github/pacificclimate/modelmeta) + +## Overview + +`modelmeta` is a Python package that provides an [Object Relational +Mapping (ORM)](http://en.wikipedia.org/wiki/Object-relational_mapping) +layer for accessing the [Pacific Climate Impacts Consortium +(PCIC)](http://www.pacificclimate.org/)\'s database of [coverage +data](http://en.wikipedia.org/wiki/Coverage_data) metadata. The package +provides model classes for each of the tables in the database. + +With this package, one can recreate the database schema in +[PostgreSQL](http://www.postgresql.org) or +[SQLite](http://www.sqlite.org) and/or use the package as an object +mapper for programmatic database access. + +`modelmeta` uses [SQLAlchemy](http://www.sqlalchemy.org) to provide the +ORM layer, and [Alembic](http://alembic.zzzcomputing.com/en/latest/) to +manage database creation and migration (see section below). + +The intent of the database itself is to separate the small, inexpensive, +structured metadata and attribute information (stored in the database) +from the expensive-to-access bulk spatiotemporal data (stored on disk in +multidimensional files). It provides an efficiently searchable index of +the bulk data files, and separates storage from indexing. + +## Installation + +Installation of this package, including system dependences, is automated through either `make` or `poethepoet` for Ubuntu 24.04: + + $ make #option 1 + $ poe setup #option 2 + +If you wish to install `modelmeta` manually, follow the steps below. + +1. Clone the repository: + + $ git clone https://github.com/pacificclimate/modelmeta + +2. Create and activate a virtual environment: + + $ cd modelmeta + $ python3 -m venv venv + $ source venv/bin/activate + $ pip install poetry + $ poetry install # --with=test for development and testing + +Scripts to populate a PCIC modelmeta database +=========================================== + +This repository contains two convenient scripts that add data files to +an existing modelmeta database so that our websites can access data from +them. They are installed when the package is installed. + +### Indexing new files with index_netcdf + +`index_netcdf` adds one or more netCDF climate data files to a PCIC +modelmeta-format database: + + index_netcdf -d postgresql://username:password@monsoon.pcic.uvic.ca/database /path/to/files/*.nc + +Usernames and passwords can be found in Team Password Manager. To add +files to the data portal, use database `pcic_meta`; to add files to PCEX +or Plan2adapt, use database `ce_meta_12f290b63791`. + +In order to determine the metadata of the file, the `index_metadata` +script scans its netCDF attributes. If the file does not have all the +[required +attributes](https://pcic.uvic.ca/confluence/display/CSG/PCIC+metadata+standard+for+downscaled+data+and+hydrology+modelling+data) +specified, the `index_metadata` script will be unable to proceed. You +can look at a file\'s attributes with the command: + + ncdump -h file.nc + +and update attributes using the `update_metadata` script in the +[climate-explorer-data-prep](https://github.com/pacificclimate/climate-explorer-data-prep) +respository. If you update file attributes, log your update YAML and a +list of which files you used with in in the +[data-prep-actions](https://github.com/pacificclimate/data-prep-actions) +repository, in case you need to reprocess or check the files later. + +### Making files accessible to PCIC projects with associate_ensemble + +Once files have been indexed into the database, they need to be added to +individual ensembles; each ensemble is associated with a particular +project or website and contains all data files needed to support the +functioning of that component. In most cases, a file will be added to +more than one ensemble: + + associate_ensemble -n ensemble_name -v 1 -d postgresql://username:password@db.pcic.uvic.ca/database /path/to/files/*.nc + +**Available ensembles, or where should I put this data anyway?** + +Most ensembles represent groupings of related files that users can +interact with (view maps, download data, create graphs, etc) using a +specific PCIC tool. Plan2adapt, the data portal, SCIP, and PCEX all use +ensembles in this way. + +Plan2adapt uses a single ensemble which represents a list of all the +files a user can view. The name of this ensemble is set when plan2adapt +is deployed, as the environment variable `REACT_APP_ENSEMBLE_NAME`. You +can see the environment variables for a docker container running +plan2adapt with `docker exec container_name env`. + +The data portal uses a separate ensemble for each portal, which +represents a list of the data files a user can download from that +portal. Each portal\'s ensemble is hard-coded in that portal\'s +definition file, in +[pdp/portals](https://github.com/pacificclimate/pdp/tree/master/pdp/portals) +. + +PCEX is flexible about which ensembles it uses. A PCEX URL encodes both +a UI and an ensemble which specifies which data is to be viewed with +that UI. In theory you can look at any ensemble with any UI, but in +practice, UIs make assumptions about the type of data available and most +combinations won\'t work. In most cases, users access the various PCEX +UIs pages via the [link bar at the top of the +page](https://github.com/pacificclimate/climate-explorer-frontend/blob/master/src/components/DataTool.js). +The `navSubpath` variable has the UI before the slash and the ensemble +after it. PCEX UIs that display hydrological data for a watershed also +have an additional ensemble that contains files that describe the +geography of the watershed; this data cannot be directly viewed by the +user but is required for some calculations. A list of these geographic +ensembles can be +[found](https://github.com/pacificclimate/climate-explorer-frontend/blob/master/src/data-services/ce-backend.js) +in `getWatershedGeographyName()`. + +SCIP is currently hardcoded to use an ensemble named +\"scip_fraser_bccoast\". + +There are also two special ensembles used by PCIC internal tools, not +web portals. + +- The `all_files` ensemble in the `ce_meta_12f290b63791` contains + every file in the database, with the exception of time-invariant + files. It is used with various scripts that + [test](https://github.com/pacificclimate/data-prep-actions/blob/master/actions/test-ncwms-instance/DESCRIPTION.md) + new functionality across all files. +- The `p2a_rules` ensemble in the `ce_meta_12f290b63791` database + contains all the information needed by plan2adapt\'s rules engine; + it is used by the + [scripts](https://github.com/pacificclimate/data-prep-actions/blob/master/actions/precalculate-p2a-regions/DESCRIPTION.md) + which pre-generate rules engine results for plan2adapt, which are + too slow to process in real time. + +### Deleting files from the databases + +Unfortunately, we don\'t currently have a script that can delete files +from the databases. If you accidentally index a file with bad metadata +and need to get rid of it, at present the only way is to log on to the +database directly with `psql` or `pgadmin`. + +## What is climate coverage data? + +Climate coverage data (or \"raster data\" or \"spatiotemporal data\") +consist of large data fields, typically over two or three dimensions in +space plus a time dimension. Depending on the resolution in each axis, +the data can typically be quite large in size. Typically there are +several-to-many output quantities (e.g. temperature, precipiation, wind +speed/direction) and often there can be multiple scenarios, multiple +model implementations, and multiple runs of each model further +exacerbating the size of the data. + +## Managing database migrations + +### Introduction + +Modifications to `modelmeta`\'s schema definition are now managed using +[Alembic](https://alembic.sqlalchemy.org/en/latest/), a database migration tool based on SQLAlchemy. + +In short, Alembic supports and disciplines two processes of database +schema change: + +- Creation of database migration scripts (Python programs) that modify + the schema of a database. +- Application of migrations to specific database instances. + - In particular, Alembic can be used to *create* a new instance of + a `modelmeta` database by migrating an empty database to the + current state. This is described in detail below. + +For more information, see the [Alembic +tutorial](http://alembic.zzzcomputing.com/en/latest/tutorial.html). + +### History + +The existing instance of a `modelmeta` database (`monsoon/pcic_meta`) +was created prior to the adoption of Alembic, and therefore the timeline +for Alembic database migrations is slightly confusing. + +Timeline: + +- *the distant past*: `pcic_meta` is created by mysterious primeval + processes. +- *somewhat later*: `modelmeta` is defined using SQLAlchemy, mapping + most (but not all) features of the existing `pcic_meta` database + into an ORM. +- 2017-07-18: + - Alembic is introduced. + - Alembic is used to create migration `614911daf883` that adds + item `seasonal` to `timescale` Enum. +- 2017-08-01: + - The SQLAlchemy ORM is updated to reflect all features of the + `pcic_meta` database. This mainly involves adding some missing + indexes and constraints. + - Alembic is used to create a logically-previous migration + `7847aa3c1b39` that creates the initial database schema from an + empty database. + - The add-seasonal migration is modified to logically follow the + initial-create migration. + +#### Creating a new database + +##### For a Postgres database + +A Postgres database is somewhat more elaborate to set up, but it is also +the foundation of a production database, not least because we use +PostGIS. + +Instructions: + +1. Choose a name for your new database/schema, e.g., `ce_meta`. + +2. On the server of your choice (e.g., `monsoon`): + + **Note**: These operations must be performed with high-level + permissions. See the System Administrator to have these done or + obtain permissions. + + For a record of such a creation, see [Redmine Issue + 696](https://redmine.pacificclimate.org/issues/696). Permission + setup was more complicated than anticipated. + + a. Create a new database with the chosen name, e.g., `ce_meta`. + + b. Within that database, create a new schema with the chosen name, + e.g., `ce_meta`. + + c. Create new users, with the following permissions: + + - `ce_meta` (database owner): full permissions for table + creation and read-write permissions in schemas `ce_meta` and + `public` + - `ce_meta_rw` (database writer): read-write permissions in + schemas `ce_meta` and `public` + - `ce_meta_ro` (database reader): read-only permissions in + schemas `ce_meta` and `public` + + and for each of them + + - `search_path = ce_meta,public` + + d. [Enable PostGIS in the new + database](http://postgis.net/install/). + + - `CREATE EXTENSION postgis;` + - This creates the table `spatial_ref_sys` in schema `public`. + Check that. + +3. Add a DSN for your new database, including the appropriate user + name, to `alembic.ini`. For example: + + [prod_ce_meta] + sqlalchemy.url = postgresql://ce_meta@monsoon.pcic.uvic.ca/ce_meta + +4. Create your new database with Alembic by ugrading the empty database + to `head`: + + alembic -x db=prod_ce_meta upgrade head + +5. Have a beer. + +##### For a SQLite database + +A SQLite database is very simple to set up, but is normally used only +for testing. + +1. Add a DSN for your new database to `alembic.ini`. This database need + not exist yet (although the path does). For example: + + [my_test_database] + sqlalchemy.url = sqlite:///path/to/test.sqlite + +2. Create your new database with Alembic by ugrading the non-existent + database to `head`: + + alembic -x db=my_test_database upgrade head + +3. Have a beer. Or at least a soda. + +### Updating the existing `pcic_meta` database + +**DEPRECATED**: [Decision taken not to modify +pcic_meta](https://pcic.uvic.ca/confluence/display/CSG/pcic_meta%3A+Current+contents+and+update+plan+2017-Jul) +This content is retained in case that decision is revised in future. + +This section is only of interest to PCIC. + +#### Initialization + +Status: NOT DONE + +The following things need to be done ONCE in order to bring `pcic_meta` +under management by Alembic. + +1. The table `pcic_meta.alembic_version` has already been created in + `pcic_meta` by earlier operations. Its content is currently `null`. +2. Place the value `7847aa3c1b39` in the single row and column of table + `pcic_meta.alembic_version` in `pcic_meta`. + - This fakes the migration from an empty database to its nominal + initial state (before add-seasonal migration). + +#### Ongoing migrations + +Once the initialization steps have been completed, ongoing migrations +are simple and standard: + +1. Apply later migrations: `alembic -x db=prod_pcic_meta upgrade head` + - At the time of this writing (2017-08-01), that would be + migration `614911daf883`. diff --git a/README.rst b/README.rst index f544ea8..32e5bdf 100644 --- a/README.rst +++ b/README.rst @@ -35,20 +35,16 @@ files). It provides an efficiently searchable index of the bulk data files, and Installation ============ -Installation is fully automated through ``make``:: - - $ make - -If you wish to install ``modelmeta`` manually, follow the steps below. +Installation is automated via ``poetry``. #. Clone the repository:: $ git clone https://github.com/pacificclimate/modelmeta -#. Create a virtual environment:: +#. Install :: $ cd modelmeta - $ poetry install # --with=test for development and testing + $ poetry install # add "--extras test" for development and testing Scripts to populate a PCIC modelmeta database diff --git a/poetry.lock b/poetry.lock index 04f5bb5..c22f480 100644 --- a/poetry.lock +++ b/poetry.lock @@ -629,6 +629,19 @@ files = [ {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, ] +[[package]] +name = "pastel" +version = "0.2.1" +description = "Bring colors to your terminal." +optional = true +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["main"] +markers = "extra == \"poe\"" +files = [ + {file = "pastel-0.2.1-py2.py3-none-any.whl", hash = "sha256:4349225fcdf6c2bb34d483e523475de5bb04a5c10ef711263452cb37d7dd4364"}, + {file = "pastel-0.2.1.tar.gz", hash = "sha256:e6581ac04e973cac858828c6202c1e1e81fee1dc7de7683f3e1ffe0bfd8a573d"}, +] + [[package]] name = "pg8000" version = "1.31.2" @@ -663,6 +676,27 @@ files = [ dev = ["pre-commit", "tox"] testing = ["pytest", "pytest-benchmark"] +[[package]] +name = "poethepoet" +version = "0.34.0" +description = "A task runner that works well with poetry." +optional = true +python-versions = ">=3.9" +groups = ["main"] +markers = "extra == \"poe\"" +files = [ + {file = "poethepoet-0.34.0-py3-none-any.whl", hash = "sha256:c472d6f0fdb341b48d346f4ccd49779840c15b30dfd6bc6347a80d6274b5e34e"}, + {file = "poethepoet-0.34.0.tar.gz", hash = "sha256:86203acce555bbfe45cb6ccac61ba8b16a5784264484195874da457ddabf5850"}, +] + +[package.dependencies] +pastel = ">=0.2.1,<0.3.0" +pyyaml = ">=6.0.2,<7.0" +tomli = {version = ">=1.2.2", markers = "python_version < \"3.11\""} + +[package.extras] +poetry-plugin = ["poetry (>=1.2.0,<3.0.0) ; python_version < \"4.0\""] + [[package]] name = "psycopg2" version = "2.9.10" @@ -733,6 +767,70 @@ files = [ [package.dependencies] six = ">=1.5" +[[package]] +name = "pyyaml" +version = "6.0.2" +description = "YAML parser and emitter for Python" +optional = true +python-versions = ">=3.8" +groups = ["main"] +markers = "extra == \"poe\"" +files = [ + {file = "PyYAML-6.0.2-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0a9a2848a5b7feac301353437eb7d5957887edbf81d56e903999a75a3d743086"}, + {file = "PyYAML-6.0.2-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:29717114e51c84ddfba879543fb232a6ed60086602313ca38cce623c1d62cfbf"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8824b5a04a04a047e72eea5cec3bc266db09e35de6bdfe34c9436ac5ee27d237"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7c36280e6fb8385e520936c3cb3b8042851904eba0e58d277dca80a5cfed590b"}, + {file = "PyYAML-6.0.2-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:ec031d5d2feb36d1d1a24380e4db6d43695f3748343d99434e6f5f9156aaa2ed"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:936d68689298c36b53b29f23c6dbb74de12b4ac12ca6cfe0e047bedceea56180"}, + {file = "PyYAML-6.0.2-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:23502f431948090f597378482b4812b0caae32c22213aecf3b55325e049a6c68"}, + {file = "PyYAML-6.0.2-cp310-cp310-win32.whl", hash = "sha256:2e99c6826ffa974fe6e27cdb5ed0021786b03fc98e5ee3c5bfe1fd5015f42b99"}, + {file = "PyYAML-6.0.2-cp310-cp310-win_amd64.whl", hash = "sha256:a4d3091415f010369ae4ed1fc6b79def9416358877534caf6a0fdd2146c87a3e"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:cc1c1159b3d456576af7a3e4d1ba7e6924cb39de8f67111c735f6fc832082774"}, + {file = "PyYAML-6.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:1e2120ef853f59c7419231f3bf4e7021f1b936f6ebd222406c3b60212205d2ee"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5d225db5a45f21e78dd9358e58a98702a0302f2659a3c6cd320564b75b86f47c"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5ac9328ec4831237bec75defaf839f7d4564be1e6b25ac710bd1a96321cc8317"}, + {file = "PyYAML-6.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3ad2a3decf9aaba3d29c8f537ac4b243e36bef957511b4766cb0057d32b0be85"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:ff3824dc5261f50c9b0dfb3be22b4567a6f938ccce4587b38952d85fd9e9afe4"}, + {file = "PyYAML-6.0.2-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:797b4f722ffa07cc8d62053e4cff1486fa6dc094105d13fea7b1de7d8bf71c9e"}, + {file = "PyYAML-6.0.2-cp311-cp311-win32.whl", hash = "sha256:11d8f3dd2b9c1207dcaf2ee0bbbfd5991f571186ec9cc78427ba5bd32afae4b5"}, + {file = "PyYAML-6.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:e10ce637b18caea04431ce14fabcf5c64a1c61ec9c56b071a4b7ca131ca52d44"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:c70c95198c015b85feafc136515252a261a84561b7b1d51e3384e0655ddf25ab"}, + {file = "PyYAML-6.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:ce826d6ef20b1bc864f0a68340c8b3287705cae2f8b4b1d932177dcc76721725"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1f71ea527786de97d1a0cc0eacd1defc0985dcf6b3f17bb77dcfc8c34bec4dc5"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:9b22676e8097e9e22e36d6b7bda33190d0d400f345f23d4065d48f4ca7ae0425"}, + {file = "PyYAML-6.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:80bab7bfc629882493af4aa31a4cfa43a4c57c83813253626916b8c7ada83476"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:0833f8694549e586547b576dcfaba4a6b55b9e96098b36cdc7ebefe667dfed48"}, + {file = "PyYAML-6.0.2-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:8b9c7197f7cb2738065c481a0461e50ad02f18c78cd75775628afb4d7137fb3b"}, + {file = "PyYAML-6.0.2-cp312-cp312-win32.whl", hash = "sha256:ef6107725bd54b262d6dedcc2af448a266975032bc85ef0172c5f059da6325b4"}, + {file = "PyYAML-6.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:7e7401d0de89a9a855c839bc697c079a4af81cf878373abd7dc625847d25cbd8"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:efdca5630322a10774e8e98e1af481aad470dd62c3170801852d752aa7a783ba"}, + {file = "PyYAML-6.0.2-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:50187695423ffe49e2deacb8cd10510bc361faac997de9efef88badc3bb9e2d1"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0ffe8360bab4910ef1b9e87fb812d8bc0a308b0d0eef8c8f44e0254ab3b07133"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:17e311b6c678207928d649faa7cb0d7b4c26a0ba73d41e99c4fff6b6c3276484"}, + {file = "PyYAML-6.0.2-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:70b189594dbe54f75ab3a1acec5f1e3faa7e8cf2f1e08d9b561cb41b845f69d5"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:41e4e3953a79407c794916fa277a82531dd93aad34e29c2a514c2c0c5fe971cc"}, + {file = "PyYAML-6.0.2-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:68ccc6023a3400877818152ad9a1033e3db8625d899c72eacb5a668902e4d652"}, + {file = "PyYAML-6.0.2-cp313-cp313-win32.whl", hash = "sha256:bc2fa7c6b47d6bc618dd7fb02ef6fdedb1090ec036abab80d4681424b84c1183"}, + {file = "PyYAML-6.0.2-cp313-cp313-win_amd64.whl", hash = "sha256:8388ee1976c416731879ac16da0aff3f63b286ffdd57cdeb95f3f2e085687563"}, + {file = "PyYAML-6.0.2-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:24471b829b3bf607e04e88d79542a9d48bb037c2267d7927a874e6c205ca7e9a"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d7fded462629cfa4b685c5416b949ebad6cec74af5e2d42905d41e257e0869f5"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d84a1718ee396f54f3a086ea0a66d8e552b2ab2017ef8b420e92edbc841c352d"}, + {file = "PyYAML-6.0.2-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9056c1ecd25795207ad294bcf39f2db3d845767be0ea6e6a34d856f006006083"}, + {file = "PyYAML-6.0.2-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:82d09873e40955485746739bcb8b4586983670466c23382c19cffecbf1fd8706"}, + {file = "PyYAML-6.0.2-cp38-cp38-win32.whl", hash = "sha256:43fa96a3ca0d6b1812e01ced1044a003533c47f6ee8aca31724f78e93ccc089a"}, + {file = "PyYAML-6.0.2-cp38-cp38-win_amd64.whl", hash = "sha256:01179a4a8559ab5de078078f37e5c1a30d76bb88519906844fd7bdea1b7729ff"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:688ba32a1cffef67fd2e9398a2efebaea461578b0923624778664cc1c914db5d"}, + {file = "PyYAML-6.0.2-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:a8786accb172bd8afb8be14490a16625cbc387036876ab6ba70912730faf8e1f"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d8e03406cac8513435335dbab54c0d385e4a49e4945d2909a581c83647ca0290"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f753120cb8181e736c57ef7636e83f31b9c0d1722c516f7e86cf15b7aa57ff12"}, + {file = "PyYAML-6.0.2-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3b1fdb9dc17f5a7677423d508ab4f243a726dea51fa5e70992e59a7411c89d19"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:0b69e4ce7a131fe56b7e4d770c67429700908fc0752af059838b1cfb41960e4e"}, + {file = "PyYAML-6.0.2-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:a9f8c2e67970f13b16084e04f134610fd1d374bf477b17ec1599185cf611d725"}, + {file = "PyYAML-6.0.2-cp39-cp39-win32.whl", hash = "sha256:6395c297d42274772abc367baaa79683958044e5d3835486c16da75d2a694631"}, + {file = "PyYAML-6.0.2-cp39-cp39-win_amd64.whl", hash = "sha256:39693e1f8320ae4f43943590b49779ffb98acb81f788220ea932a6b6c51004d8"}, + {file = "pyyaml-6.0.2.tar.gz", hash = "sha256:d584d9ec91ad65861cc08d42e834324ef890a082e591037abe114850ff7bbc3e"}, +] + [[package]] name = "scramp" version = "1.4.5" @@ -988,7 +1086,7 @@ description = "A lil' TOML parser" optional = true python-versions = ">=3.8" groups = ["main"] -markers = "extra == \"test\" and python_version == \"3.10\"" +markers = "(extra == \"test\" or extra == \"poe\") and python_version == \"3.10\"" files = [ {file = "tomli-2.2.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:678e4fa69e4575eb77d103de3df8a895e1591b48e740211bd1067378c69e8249"}, {file = "tomli-2.2.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:023aa114dd824ade0100497eb2318602af309e5a55595f76b626d6d9f3b7b0a6"}, @@ -1037,9 +1135,10 @@ files = [ ] [extras] +poe = ["poethepoet"] test = ["alembic-verify", "lxml", "pytest", "sqlalchemy-diff", "sqlparse", "testing-postgresql"] [metadata] lock-version = "2.1" python-versions = ">=3.10,<4.0" -content-hash = "2b90a3f88381d059f0be08342970868851d49b79ef787e0399513dc1741139cd" +content-hash = "8f55fb82b66f4c45cd92039439879187b76f8d17e8970577cbd0bf540cc02a33" diff --git a/pyproject.toml b/pyproject.toml index b9d97ae..c4f8970 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -45,6 +45,7 @@ test = [ "sqlparse==0.5.3", "lxml==5.4.0", ] +poe = [ "poethepoet==0.34.0"] [[tool.poetry.source]] @@ -68,3 +69,17 @@ generate_manifest="scripts.generate_manifest:generate" markers = [ "slow: marks tests that are slow (deselect with '-m \"not slow\"')", ] + + +[tool.poe.tasks] +dependencies = """ +sudo apt-get install postgresql-16 + postgresql-client-16 + libhdf5-serial-dev + libnetcdf-dev + libspatialite-dev + postgresql-16-postgis-3 +""" +install = "poetry install" +test = "poetry run pytest" +setup = ["dependencies", "install", "test"] \ No newline at end of file diff --git a/tests/mm_cataloguer/test_index.py b/tests/mm_cataloguer/test_index.py index 527d961..067def5 100644 --- a/tests/mm_cataloguer/test_index.py +++ b/tests/mm_cataloguer/test_index.py @@ -935,7 +935,6 @@ def test_insert_data_file( ): # Have to use a datetime with no hours, min, sec because apparently # SQLite loses precision - #fake_now = freeze_utcnow(monkeypatch, 2000, 1, 2) fake_now = freeze_utcnow(monkeypatch, datetime.datetime.now(datetime.UTC).year, datetime.datetime.now(datetime.UTC).month, datetime.datetime.now(datetime.UTC).day) dim_names = tiny_any_dataset.axes_dim() data_file = check_insert( From 96cef3b4297c790898b9fffaa048696c97825b9f Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Thu, 8 May 2025 14:35:31 -0700 Subject: [PATCH 18/31] update datetime.utc --- mm_cataloguer/index_netcdf.py | 8 ++++---- tests/conftest.py | 2 +- tests/mm_cataloguer/test_index.py | 9 +++++++-- 3 files changed, 12 insertions(+), 7 deletions(-) diff --git a/mm_cataloguer/index_netcdf.py b/mm_cataloguer/index_netcdf.py index 00e35b7..cd30458 100644 --- a/mm_cataloguer/index_netcdf.py +++ b/mm_cataloguer/index_netcdf.py @@ -155,10 +155,10 @@ def seconds_since_epoch(t): """Convert a datetime to the number of seconds since the Unix epoch.""" # add a timezone, if one is missing if t.tzinfo is None: - utc_t = t.replace(tzinfo=datetime.UTC) + utc_t = t.replace(tzinfo=datetime.timezone.utc) else: utc_t = t - return (utc_t-datetime.datetime(1970, 1, 1, tzinfo=datetime.UTC)).total_seconds() + return (utc_t-datetime.datetime(1970, 1, 1, tzinfo=datetime.timezone.utc)).total_seconds() @memoize @@ -1129,7 +1129,7 @@ def insert_data_file(sesh, cf): # create.data.file.id filename=cf.filepath(converter=filepath_converter), first_1mib_md5sum=cf.first_MiB_md5sum, unique_id=cf.unique_id, - index_time=datetime.datetime.now(datetime.UTC), + index_time=datetime.datetime.now(datetime.timezone.utc), run=run, timeset=timeset, x_dim_name=dim_names.get('X', None), @@ -1193,7 +1193,7 @@ def delete_data_file(sesh, existing_data_file): def update_data_file_index_time(sesh, data_file): """Update the index time recorded for data_file""" logger.info('Updating index time (only)') - data_file.index_time = datetime.datetime.now(datetime.UTC) + data_file.index_time = datetime.datetime.now(datetime.timezone.utc) return data_file diff --git a/tests/conftest.py b/tests/conftest.py index 7ebab56..487ec40 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -81,7 +81,7 @@ def make_data_file(i, run=None, timeset=None): x_dim_name='lon', y_dim_name='lat', t_dim_name='time', - index_time=datetime.datetime.now(datetime.UTC), + index_time=datetime.datetime.now(datetime.timezone.utc), run=run, timeset=timeset, ) diff --git a/tests/mm_cataloguer/test_index.py b/tests/mm_cataloguer/test_index.py index 067def5..70cdfc7 100644 --- a/tests/mm_cataloguer/test_index.py +++ b/tests/mm_cataloguer/test_index.py @@ -135,7 +135,7 @@ def check_find_or_insert(*args, **kwargs): def freeze_utcnow(*args): - """Freeze datetime.datetime.utcnow() + """Freeze datetime.datetime.now() This would be more elegant as a fixture or decorator, but it would be a lot more work. @@ -935,7 +935,12 @@ def test_insert_data_file( ): # Have to use a datetime with no hours, min, sec because apparently # SQLite loses precision - fake_now = freeze_utcnow(monkeypatch, datetime.datetime.now(datetime.UTC).year, datetime.datetime.now(datetime.UTC).month, datetime.datetime.now(datetime.UTC).day) + fake_now = freeze_utcnow( + monkeypatch, + datetime.datetime.now(datetime.timezone.utc).year, + datetime.datetime.now(datetime.timezone.utc).month, + datetime.datetime.now(datetime.timezone.utc).day + ) dim_names = tiny_any_dataset.axes_dim() data_file = check_insert( insert_data_file, test_session_with_empty_db, tiny_any_dataset, From 2c1fffe58d6e0eb100a5b207c5d3c740f1d5c5c1 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Thu, 8 May 2025 14:47:34 -0700 Subject: [PATCH 19/31] need postgis after all --- .github/workflows/python-ci.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/.github/workflows/python-ci.yml b/.github/workflows/python-ci.yml index fb367bd..c9d50c7 100644 --- a/.github/workflows/python-ci.yml +++ b/.github/workflows/python-ci.yml @@ -23,7 +23,7 @@ jobs: - name: Install system dependencies run: | sudo apt-get update - sudo apt-get install postgresql-16 postgresql-client-16 libhdf5-serial-dev libnetcdf-dev libspatialite-dev wget + sudo apt-get install postgis postgresql-16 postgresql-client-16 libhdf5-serial-dev libnetcdf-dev libspatialite-dev wget - name: Install poetry run: | From 3f2335590f14c3b69abda83c53252a94e1de3578 Mon Sep 17 00:00:00 2001 From: James Hiebert Date: Wed, 21 May 2025 11:20:44 -0400 Subject: [PATCH 20/31] Exploratory code to mitigate netCDF4 errors An attempt to mitigate the following errors: Exception ignored in: 'netCDF4._netCDF4.Dataset.__dealloc__' AttributeError: __getattribute__ AttributeError: __getattribute__ This patch includes code to attempt to avoid memoizing open NetCDF files as well as some timing code to benchmark test results using (or not) memoization. --- mm_cataloguer/index_netcdf.py | 16 ++++++++++++++-- tests/conftest.py | 10 ++++++++++ 2 files changed, 24 insertions(+), 2 deletions(-) diff --git a/mm_cataloguer/index_netcdf.py b/mm_cataloguer/index_netcdf.py index cd30458..619836d 100644 --- a/mm_cataloguer/index_netcdf.py +++ b/mm_cataloguer/index_netcdf.py @@ -127,14 +127,26 @@ def memoize(obj): @functools.wraps(obj) def memoized(*args): + + # Usage below tries to memoize *open* NetCDF files, creating + # extraneous references to them. As a result, problems arise + # at the end of the program during finalization and + # cleanup. If the object is a closeable (like an open file) + # use the object id as the cache key. However, it turns out + # that not even this works, because the cached values are + # NetCDF variables objects that *also* hold references to the + # NetCDF files + real_args = args + args = tuple(id(arg) if hasattr(arg, 'close') else arg for arg in args) + if args in memo: return memo[args] else: - value = obj(*args) + value = obj(*real_args) memo[args] = value return value - return memoized + return obj # Helper functions diff --git a/tests/conftest.py b/tests/conftest.py index 487ec40..f883a0c 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -27,6 +27,7 @@ import os from importlib.resources import files import datetime +import time import pytest import testing.postgresql @@ -417,3 +418,12 @@ def tiny_any_dataset(request): @pytest.fixture(params=[False, True]) def insert(request): return request.param + + +@pytest.fixture(autouse=True) +def time_test_body(request): + start = time.perf_counter() + yield + end = time.perf_counter() + with open("timing.log", "a") as f: + f.write(f"{request.node.nodeid} took {end - start:.4f} seconds\n") From d957574d8dd73e5fce6b2ad9d3b7ad8ac4533b06 Mon Sep 17 00:00:00 2001 From: James Hiebert Date: Wed, 21 May 2025 11:24:43 -0400 Subject: [PATCH 21/31] Remove memoization from index_netcdf.py The memoization code in index_netcdf.py was both problematic and ineffective. As part of the keys to the cache, it used open NetCDF file objects and as part of the values of the cache were Netcdf variable objects (which also contained references to the NetCDF files). On exit, the main branch of the code would close and clean up the files, leaving everything in the cache stranged. When the cache got cleaned up, it would leave a long string of error messages: Exception ignored in: 'netCDF4._netCDF4.Dataset.__dealloc__' AttributeError: __getattribute__ AttributeError: __getattribute__ for each stranded object. While this didn't necessarily cause any real errors at execution time, it was messy. Furthermore, the expensive part of indexing is I/O: going out to read data from the disk and going out to the database. The memoization, as written, didn't actually mitigate this. It only cached objects, referencing the file. I measured the differences in the test suite between memoized and non-memoized and it was on the order of miliseconds (noise). I recommend simply removing this code, as this patch does. --- mm_cataloguer/index_netcdf.py | 39 ----------------------------------- tests/conftest.py | 9 -------- 2 files changed, 48 deletions(-) diff --git a/mm_cataloguer/index_netcdf.py b/mm_cataloguer/index_netcdf.py index 619836d..6b392b3 100644 --- a/mm_cataloguer/index_netcdf.py +++ b/mm_cataloguer/index_netcdf.py @@ -112,43 +112,6 @@ filepath_converter = 'realpath' - -# Decorators - -def memoize(obj): - """Memoize a callable object with only positional args, and where those - args are hashable. This is simple and sufficient for its application in - this code. It works in all versions of Python >= 2.7, which is not true - for many of the more featureful modules (e.g., `functools.lru_cache`). - - Adapted from http://book.pythontips.com/en/latest/function_caching.html - """ - memo = {} - - @functools.wraps(obj) - def memoized(*args): - - # Usage below tries to memoize *open* NetCDF files, creating - # extraneous references to them. As a result, problems arise - # at the end of the program during finalization and - # cleanup. If the object is a closeable (like an open file) - # use the object id as the cache key. However, it turns out - # that not even this works, because the cached values are - # NetCDF variables objects that *also* hold references to the - # NetCDF files - real_args = args - args = tuple(id(arg) if hasattr(arg, 'close') else arg for arg in args) - - if args in memo: - return memo[args] - else: - value = obj(*real_args) - memo[args] = value - return value - - return obj - - # Helper functions def is_regular_series(values, relative_tolerance=1e-6): @@ -173,7 +136,6 @@ def seconds_since_epoch(t): return (utc_t-datetime.datetime(1970, 1, 1, tzinfo=datetime.timezone.utc)).total_seconds() -@memoize def get_level_set_info(cf, var_name): """Return a dict containing information characterizing the level set (Z axis values) associated with a specified dependent variable, or @@ -203,7 +165,6 @@ def get_level_set_info(cf, var_name): } -@memoize def get_grid_info(cf, var_name): """Get information defining the Grid record corresponding to the spatial dimensions of a variable in a NetCDF file. diff --git a/tests/conftest.py b/tests/conftest.py index f883a0c..fc5168d 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -418,12 +418,3 @@ def tiny_any_dataset(request): @pytest.fixture(params=[False, True]) def insert(request): return request.param - - -@pytest.fixture(autouse=True) -def time_test_body(request): - start = time.perf_counter() - yield - end = time.perf_counter() - with open("timing.log", "a") as f: - f.write(f"{request.node.nodeid} took {end - start:.4f} seconds\n") From b79b6b829d33dd8a89728a791b7eb8a5b839336d Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Wed, 21 May 2025 18:13:44 -0700 Subject: [PATCH 22/31] delete old README --- README.md | 18 ++++ README.rst | 257 ----------------------------------------------------- 2 files changed, 18 insertions(+), 257 deletions(-) delete mode 100644 README.rst diff --git a/README.md b/README.md index 5ff26d0..7112096 100644 --- a/README.md +++ b/README.md @@ -323,3 +323,21 @@ are simple and standard: 1. Apply later migrations: `alembic -x db=prod_pcic_meta upgrade head` - At the time of this writing (2017-08-01), that would be migration `614911daf883`. + +### Creating a new database migration + +First create a new revision with this command: + +``` +alembic revision -m "" +``` + +Alembic will create a new file in `alembic/versions` with stub `upgrade()` and `downgrade()` +functions. Fill in the upgrade function to make the change you want the migration to create +(IE, drop a table, recreate it with different column names) and the downgrade function to return +to the current database configuration from the new one (IE, drop a table, recreate it with +the old column names). The `alembic.op` object has various useful database manipulation functions +for this. + +You can migrate a database to the new revision with the `alembic upgrade head` command discussed +earlier. \ No newline at end of file diff --git a/README.rst b/README.rst deleted file mode 100644 index 32e5bdf..0000000 --- a/README.rst +++ /dev/null @@ -1,257 +0,0 @@ -========= -modelmeta -========= - -.. image:: https://github.com/pacificclimate/modelmeta/workflows/Python%20CI/badge.svg - :target: https://github.com/pacificclimate/modelmeta - -.. image:: https://github.com/pacificclimate/modelmeta/workflows/Pypi%20Publishing/badge.svg - :target: https://github.com/pacificclimate/modelmeta - -.. image:: https://codeclimate.com/github/pacificclimate/modelmeta/badges/gpa.svg - :target: https://codeclimate.com/github/pacificclimate/modelmeta - :alt: Code Climate - -Overview -======== - -``modelmeta`` is a Python package that provides an -`Object Relational Mapping (ORM) `_ layer -for accessing the `Pacific Climate Impacts Consortium (PCIC) `_'s -database of `coverage data `_ metadata. -The package provides model classes for each of the tables in the database. - -With this package, one can recreate the database schema in `PostgreSQL `_ -or `SQLite `_ and/or use the package as an object mapper for programmatic database access. - -``modelmeta`` uses `SQLAlchemy `_ to provide the ORM layer, and -`Alembic `_ to manage database creation and migration (see section -below). - -The intent of the database itself is to separate the small, inexpensive, structured metadata and attribute information -(stored in the database) from the expensive-to-access bulk spatiotemporal data (stored on disk in multidimensional -files). It provides an efficiently searchable index of the bulk data files, and separates storage from indexing. - -Installation -============ - -Installation is automated via ``poetry``. - -#. Clone the repository:: - - $ git clone https://github.com/pacificclimate/modelmeta - -#. Install :: - - $ cd modelmeta - $ poetry install # add "--extras test" for development and testing - - -Scripts to populate a PCIC modelmeta database -=========================================== - -This repository contains two convenient scripts that add data files to an existing modelmeta database so that our websites can access data from them. They are installed when the package is installed. - -Indexing new files with index_netcdf ------------------------------------- -``index_netcdf`` adds one or more netCDF climate data files to a PCIC modelmeta-format database:: - - index_netcdf -d postgresql://username:password@monsoon.pcic.uvic.ca/database /path/to/files/*.nc - -Usernames and passwords can be found in Team Password Manager. To add files to the data portal, use database ``pcic_meta``; to add files to PCEX or Plan2adapt, use database ``ce_meta_12f290b63791``. - -In order to determine the metadata of the file, the ``index_metadata`` script scans its netCDF attributes. If the file does not have all the `required attributes `_ specified, the ``index_metadata`` script will be unable to proceed. You can look at a file's attributes with the command:: - - ncdump -h file.nc - - -and update attributes using the ``update_metadata`` script in the `climate-explorer-data-prep `_ respository. If you update file attributes, log your update YAML and a list of which files you used with in in the `data-prep-actions `_ repository, in case you need to reprocess or check the files later. - -Making files accessible to PCIC projects with associate_ensemble ----------------------------------------------------------------- - -Once files have been indexed into the database, they need to be added to individual ensembles; each ensemble is associated with a particular project or website and contains all data files needed to support the functioning of that component. In most cases, a file will be added to more than one ensemble:: - - associate_ensemble -n ensemble_name -v 1 -d postgresql://username:password@db.pcic.uvic.ca/database /path/to/files/*.nc - -**Available ensembles, or where should I put this data anyway?** - -Most ensembles represent groupings of related files that users can interact with (view maps, download data, create graphs, etc) using a specific PCIC tool. Plan2adapt, the data portal, SCIP, and PCEX all use ensembles in this way. - -Plan2adapt uses a single ensemble which represents a list of all the files a user can view. The name of this ensemble is set when plan2adapt is deployed, as the environment variable ``REACT_APP_ENSEMBLE_NAME``. You can see the environment variables for a docker container running plan2adapt with ``docker exec container_name env``. - -The data portal uses a separate ensemble for each portal, which represents a list of the data files a user can download from that portal. Each portal's ensemble is hard-coded in that portal's definition file, in `pdp/portals `_ . - -PCEX is flexible about which ensembles it uses. A PCEX URL encodes both a UI and an ensemble which specifies which data is to be viewed with that UI. In theory you can look at any ensemble with any UI, but in practice, UIs make assumptions about the type of data available and most combinations won't work. In most cases, users access the various PCEX UIs pages via the `link bar at the top of the page `_. The ``navSubpath`` variable has the UI before the slash and the ensemble after it. PCEX UIs that display hydrological data for a watershed also have an additional ensemble that contains files that describe the geography of the watershed; this data cannot be directly viewed by the user but is required for some calculations. A list of these geographic ensembles can be `found `_ in ``getWatershedGeographyName()``. - -SCIP is currently hardcoded to use an ensemble named "scip_fraser_bccoast". - -There are also two special ensembles used by PCIC internal tools, not web portals. - -* The ``all_files`` ensemble in the ``ce_meta_12f290b63791`` contains every file in the database, with the exception of time-invariant files. It is used with various scripts that `test `_ new functionality across all files. - -* The ``p2a_rules`` ensemble in the ``ce_meta_12f290b63791`` database contains all the information needed by plan2adapt's rules engine; it is used by the `scripts `_ which pre-generate rules engine results for plan2adapt, which are too slow to process in real time. - - -Deleting files from the databases ---------------------------------- - -Unfortunately, we don't currently have a script that can delete files from the databases. If you accidentally index a file with bad metadata and need to get rid of it, at present the only way is to log on to the database directly with ``psql`` or ``pgadmin``. - - -What is climate coverage data? -============================== - -Climate coverage data (or "raster data" or "spatiotemporal data") consist of large data fields, typically over -two or three dimensions in space plus a time dimension. Depending on the resolution in each axis, the data can -typically be quite large in size. Typically there are several-to-many output quantities (e.g. temperature, -precipiation, wind speed/direction) and often there can be multiple scenarios, multiple model implementations, -and multiple runs of each model further exacerbating the size of the data. - -Managing database migrations -============================ - -Introduction ------------- - -Modifications to ``modelmeta``'s schema definition are now managed using -`Alembic`_, a database migration tool based on SQLAlchemy. - -In short, Alembic supports and disciplines two processes of database schema change: - -- Creation of database migration scripts (Python programs) that modify the schema of a database. - -- Application of migrations to specific database instances. - - - In particular, Alembic can be used to *create* a new instance of a ``modelmeta`` database by migrating an - empty database to the current state. This is described in detail below. - -For more information, see the `Alembic tutorial `_. - -History -------- - -The existing instance of a ``modelmeta`` database (``monsoon/pcic_meta``) was created prior to the adoption of -Alembic, and therefore the timeline for Alembic database migrations is slightly confusing. - -Timeline: - -- *the distant past*: ``pcic_meta`` is created by mysterious primeval processes. - -- *somewhat later*: ``modelmeta`` is defined using SQLAlchemy, mapping most (but not all) features of the existing - ``pcic_meta`` database into an ORM. - -- 2017-07-18: - - - Alembic is introduced. - - Alembic is used to create migration ``614911daf883`` that adds item ``seasonal`` to ``timescale`` Enum. - -- 2017-08-01: - - - The SQLAlchemy ORM is updated to reflect all features of the ``pcic_meta`` database. - This mainly involves adding some missing indexes and constraints. - - - Alembic is used to create a logically-previous migration ``7847aa3c1b39`` that creates the initial - database schema from an empty database. - - - The add-seasonal migration is modified to logically follow the initial-create migration. - -Creating a new database -~~~~~~~~~~~~~~~~~~~~~~~ - -For a Postgres database -+++++++++++++++++++++++ - -A Postgres database is somewhat more elaborate to set up, but it is also the foundation of a production -database, not least because we use PostGIS. - -Instructions: - -#. Choose a name for your new database/schema, e.g., ``ce_meta``. - -#. On the server of your choice (e.g., ``monsoon``): - - **Note**: These operations must be performed with high-level permissions. - See the System Administrator to have these done or obtain permissions. - - For a record of such a creation, see `Redmine Issue 696 `_. - Permission setup was more complicated than anticipated. - - a. Create a new database with the chosen name, e.g., ``ce_meta``. - - #. Within that database, create a new schema with the chosen name, e.g., ``ce_meta``. - - #. Create new users, with the following permissions: - - - ``ce_meta`` (database owner): full permissions for table creation and read-write permissions - in schemas ``ce_meta`` and ``public`` - - ``ce_meta_rw`` (database writer): read-write permissions in schemas ``ce_meta`` and ``public`` - - ``ce_meta_ro`` (database reader): read-only permissions in schemas ``ce_meta`` and ``public`` - - and for each of them - - - ``search_path = ce_meta,public`` - - #. `Enable PostGIS in the new database `_. - - - ``CREATE EXTENSION postgis;`` - - This creates the table ``spatial_ref_sys`` in schema ``public``. Check that. - -#. Add a DSN for your new database, including the appropriate user name, to ``alembic.ini``. For example:: - - [prod_ce_meta] - sqlalchemy.url = postgresql://ce_meta@monsoon.pcic.uvic.ca/ce_meta - -#. Create your new database with Alembic by ugrading the empty database to ``head``:: - - alembic -x db=prod_ce_meta upgrade head - -#. Have a beer. - -For a SQLite database -+++++++++++++++++++++ - -A SQLite database is very simple to set up, but is normally used only for testing. - -#. Add a DSN for your new database to ``alembic.ini``. This database need not exist yet (although the path does). - For example:: - - [my_test_database] - sqlalchemy.url = sqlite:///path/to/test.sqlite - -#. Create your new database with Alembic by ugrading the non-existent database to ``head``:: - - alembic -x db=my_test_database upgrade head - -#. Have a beer. Or at least a soda. - -Updating the existing ``pcic_meta`` database --------------------------------------------- - -**DEPRECATED**: `Decision taken not to modify pcic_meta `_ -This content is retained in case that decision is revised in future. - -This section is only of interest to PCIC. - -Initialization -~~~~~~~~~~~~~~ - -Status: NOT DONE - -The following things need to be done ONCE in order to bring ``pcic_meta`` under management by Alembic. - -#. The table ``pcic_meta.alembic_version`` has already been created in ``pcic_meta`` by earlier operations. - Its content is currently ``null``. - -#. Place the value ``7847aa3c1b39`` in the single row and column of table ``pcic_meta.alembic_version`` in ``pcic_meta``. - - - This fakes the migration from an empty database to its nominal initial state (before add-seasonal migration). - -Ongoing migrations -~~~~~~~~~~~~~~~~~~ - -Once the initialization steps have been completed, ongoing migrations are simple and standard: - -#. Apply later migrations: ``alembic -x db=prod_pcic_meta upgrade head`` - - - At the time of this writing (2017-08-01), that would be migration ``614911daf883``. From 37a4f8c96b1dd1056bc83004c90126ed0096392f Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Wed, 21 May 2025 18:36:51 -0700 Subject: [PATCH 23/31] replace back_ref with back_populates --- modelmeta/v2.py | 5 +++-- pyproject.toml | 2 +- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/modelmeta/v2.py b/modelmeta/v2.py index 743658b..9478f19 100644 --- a/modelmeta/v2.py +++ b/modelmeta/v2.py @@ -619,7 +619,8 @@ class Variable(Base): name = Column('variable_name', String(length=64), nullable=False) # relation definitions - variable_aliases = relationship('VariableAlias', primaryjoin='Variable.variable_alias_id==VariableAlias.id') + variable_aliases = relationship('VariableAlias', primaryjoin='Variable.variable_alias_id==VariableAlias.id', + back_populates="variable") data_files_variables = relationship('DataFileVariable', primaryjoin='Variable.variable_alias_id==VariableAlias.id', secondary='variable_aliases', @@ -647,7 +648,7 @@ class VariableAlias(Base): secondary='data_file_variables', secondaryjoin='DataFileVariable.data_file_id==DataFile.id', backref=backref('variable_aliases')) - variable = relationship("Variable", backref=backref('variable_alias')) + variable = relationship("Variable", back_populates="variable_aliases") def __repr__(self): return obj_repr('id long_name standard_name units', self) diff --git a/pyproject.toml b/pyproject.toml index c4f8970..b5e5ea5 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -6,7 +6,7 @@ build-backend = "poetry.core.masonry.api" name = "modelmeta" version = "0.1.2" requires-python = ">=3.10,<4.0" -readme = "README.rst" +readme = "README.md" description = "An ORM representation of the model meta database" authors = [ {name = "James Hiebert", email = "hiebert@uvic.ca"}, From 1ef1a42d0103fdb19d2048b5968d8116de62dd56 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Tue, 27 May 2025 17:51:47 -0700 Subject: [PATCH 24/31] fix scalar subquery --- mm_cataloguer/index_netcdf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/mm_cataloguer/index_netcdf.py b/mm_cataloguer/index_netcdf.py index 6b392b3..fed4631 100644 --- a/mm_cataloguer/index_netcdf.py +++ b/mm_cataloguer/index_netcdf.py @@ -546,7 +546,7 @@ def insert_spatial_ref_sys(sesh, cf, var_name): ) .cte(name='next_srid') ) - id = select(next_srid.c.next_srid) # Used in two places + id = select(next_srid.c.next_srid).scalar_subquery() # Used in two places proj4_string = cf.proj4_string(var_name, default=default_proj4) @@ -982,7 +982,7 @@ def find_timeset(sesh, cf): .filter(TimeSet.time_resolution == cf.time_resolution) .filter(TimeSet.num_times == int(cf.time_var.size)) .filter(TimeSet.calendar == cf.time_var.calendar) - .first() + .first() #this is where the error is. ) From 99aa55381bab707078dc889aece33cb46159689e Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Wed, 28 May 2025 16:39:22 -0700 Subject: [PATCH 25/31] mark many:many relationships "viewonly" --- modelmeta/v2.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modelmeta/v2.py b/modelmeta/v2.py index 9478f19..a6bbd3b 100644 --- a/modelmeta/v2.py +++ b/modelmeta/v2.py @@ -624,7 +624,8 @@ class Variable(Base): data_files_variables = relationship('DataFileVariable', primaryjoin='Variable.variable_alias_id==VariableAlias.id', secondary='variable_aliases', - secondaryjoin='VariableAlias.id==DataFileVariable.variable_alias_id') + secondaryjoin='VariableAlias.id==DataFileVariable.variable_alias_id', + viewonly=True) def __repr__(self): return obj_repr('id name description variable_alias_id', self) @@ -646,7 +647,8 @@ class VariableAlias(Base): data_files = relationship('DataFile', primaryjoin='VariableAlias.id==DataFileVariable.variable_alias_id', secondary='data_file_variables', - secondaryjoin='DataFileVariable.data_file_id==DataFile.id', + secondaryjoin='DataFileVariable.data_file_id==DataFile.id', + viewonly=True, backref=backref('variable_aliases')) variable = relationship("Variable", back_populates="variable_aliases") From 675dfc877feadf24223fe07f1c5a1f34ea4df300 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Thu, 29 May 2025 10:34:49 -0700 Subject: [PATCH 26/31] typo in version number --- pyproject.toml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/pyproject.toml b/pyproject.toml index b5e5ea5..59b599b 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -4,7 +4,7 @@ build-backend = "poetry.core.masonry.api" [project] name = "modelmeta" -version = "0.1.2" +version = "1.0.2" requires-python = ">=3.10,<4.0" readme = "README.md" description = "An ORM representation of the model meta database" From 67db10eccdbbc18cad61ccc5d364670eb3ec7b8c Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Thu, 29 May 2025 14:10:19 -0700 Subject: [PATCH 27/31] tidy up some comment detritus --- scripts/associate_ensemble.py | 1 - scripts/copyproddb.py | 1 - scripts/generate_manifest.py | 1 - scripts/index_netcdf.py | 1 - scripts/list.py | 2 -- scripts/list_csv.py | 3 +-- scripts/mktestdb.py | 1 - scripts/ncwms_configurator.py | 2 -- 8 files changed, 1 insertion(+), 11 deletions(-) diff --git a/scripts/associate_ensemble.py b/scripts/associate_ensemble.py index 3cdc07e..5c5ee82 100644 --- a/scripts/associate_ensemble.py +++ b/scripts/associate_ensemble.py @@ -4,7 +4,6 @@ from mm_cataloguer.associate_ensemble import main def associate(): - #if __name__ == '__main__': parser = ArgumentParser(description='Associate an ensemble to datafiles') parser.add_argument( '-d', '--dsn', required=True, diff --git a/scripts/copyproddb.py b/scripts/copyproddb.py index 49f184e..02e2c3b 100644 --- a/scripts/copyproddb.py +++ b/scripts/copyproddb.py @@ -14,7 +14,6 @@ class GenericMapper(Base): return GenericMapper def copy(): - #if __name__ == '__main__': parser = ArgumentParser() parser.add_argument("-d", "--dsn", help="Source database DSN from which to read") parser.add_argument("-o", "--outdsn", help="Destination database DSN. Default is output.sqlite in current directory") diff --git a/scripts/generate_manifest.py b/scripts/generate_manifest.py index a8f100e..df11653 100644 --- a/scripts/generate_manifest.py +++ b/scripts/generate_manifest.py @@ -6,7 +6,6 @@ from mm_cataloguer.generate_manifest import generate_manifest def generate(): - #if __name__ == '__main__': parser = ArgumentParser( description='Generate manifest of files requested from database') parser.add_argument("-c", "--connection_string", help="DSN for modelmeta database") diff --git a/scripts/index_netcdf.py b/scripts/index_netcdf.py index c0e9e9b..3f8896b 100644 --- a/scripts/index_netcdf.py +++ b/scripts/index_netcdf.py @@ -4,7 +4,6 @@ from mm_cataloguer.index_netcdf import index_netcdf_files def index(): - # if __name__ == '__main__': parser = ArgumentParser( description='Index PCIC metadata standard compliant NetCDF files ' 'into modelmeta database') diff --git a/scripts/list.py b/scripts/list.py index af49a9d..8924cd4 100644 --- a/scripts/list.py +++ b/scripts/list.py @@ -30,8 +30,6 @@ list_filepaths, list_dirpaths def list(): - # if __name__ == '__main__': - main_parser = ArgumentParser( description='Tools for listing and summarizing contents of a ' 'modelmeta database.' diff --git a/scripts/list_csv.py b/scripts/list_csv.py index 922256d..55de6e3 100644 --- a/scripts/list_csv.py +++ b/scripts/list_csv.py @@ -9,7 +9,6 @@ from mm_cataloguer.list_csv import main def list(): - # if __name__ == '__main__': parser = ArgumentParser( description='List contents of a modelmeta database into a CSV file. ' 'Filename is fixed: modelmeta.csv' @@ -20,4 +19,4 @@ def list(): help="Source database DSN from which to read" ) args = parser.parse_args() - main(args.dsn) \ No newline at end of file + main(args.dsn) diff --git a/scripts/mktestdb.py b/scripts/mktestdb.py index a5f36f3..e050986 100644 --- a/scripts/mktestdb.py +++ b/scripts/mktestdb.py @@ -7,7 +7,6 @@ from sqlalchemy.schema import MetaData def make_test(): - # if __name__ == '__main__': parser = ArgumentParser() parser.add_argument("-d", "--dsn", help="Source database DSN from which to read") parser.add_argument("-e", "--ensemble", help="Ensemble to copy from the database") diff --git a/scripts/ncwms_configurator.py b/scripts/ncwms_configurator.py index db9880b..8216440 100644 --- a/scripts/ncwms_configurator.py +++ b/scripts/ncwms_configurator.py @@ -7,8 +7,6 @@ from ncwms_configurator import create, update def configurator(): - # if __name__ == '__main__': - logging.basicConfig(stream=sys.stdout, level=logging.INFO) parser = ArgumentParser() From c142820d2e1c7c4eca2244a2efefecc5040316c8 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Thu, 29 May 2025 21:45:03 -0700 Subject: [PATCH 28/31] untangle run/timeset/datafile --- modelmeta/v2.py | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/modelmeta/v2.py b/modelmeta/v2.py index a6bbd3b..39abfef 100644 --- a/modelmeta/v2.py +++ b/modelmeta/v2.py @@ -540,7 +540,8 @@ class Run(Base): time_set = relationship('TimeSet', primaryjoin='Run.id==DataFile.run_id', secondary='data_files', - secondaryjoin='DataFile.time_set_id==TimeSet.id') + secondaryjoin='DataFile.time_set_id==TimeSet.id', + viewonly=True) files = relationship("DataFile", backref=backref('run', lazy='joined'), lazy='joined') From 4fe32d1f706db97880af556a6295d36bfe88a341 Mon Sep 17 00:00:00 2001 From: Lee Zeman Date: Fri, 30 May 2025 10:48:32 -0700 Subject: [PATCH 29/31] untagle DSG timeseries --- modelmeta/v2.py | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/modelmeta/v2.py b/modelmeta/v2.py index 39abfef..8d22ece 100644 --- a/modelmeta/v2.py +++ b/modelmeta/v2.py @@ -172,7 +172,8 @@ class DataFileVariableDSGTimeSeries(DataFileVariable): stations = relationship( 'Station', secondary='data_file_variables_dsg_time_series_x_stations', - back_populates='data_file_variables') + back_populates='data_file_variables', + viewonly=True) __mapper_args__ = { 'polymorphic_identity':'dsg_time_series', @@ -201,7 +202,8 @@ class Station(Base): data_file_variables = relationship( 'DataFileVariableDSGTimeSeries', secondary='data_file_variables_dsg_time_series_x_stations', - back_populates='stations') + back_populates='stations', + viewonly=True) def __repr__(self): From 0dc9642538f637a35a7a50e6809251e40f867b63 Mon Sep 17 00:00:00 2001 From: James Hiebert Date: Tue, 10 Jun 2025 16:36:08 -0700 Subject: [PATCH 30/31] Removed unused test code --- modelmeta/v1.py | 9 --------- 1 file changed, 9 deletions(-) diff --git a/modelmeta/v1.py b/modelmeta/v1.py index 071c2d6..99f3e4e 100644 --- a/modelmeta/v1.py +++ b/modelmeta/v1.py @@ -194,12 +194,3 @@ class QCFlag(Base): # __tablename__ = 'times' # timestep = Column(DateTime) # time_set_id = Column(Integer, ForeignKey('time_sets.time_set_id')) - -test_dsn = 'sqlite+pysqlite:///{0}'.format((files('modelmeta') / 'data/mddb-v1.sqlite').resolve()) - -def test_session(): - '''This creates a testing database session that can be used as a test fixture. - ''' - engine = create_engine(test_dsn) - Session = sessionmaker(bind=engine) - return Session() From 8680799d98224cc3c2de0841db695295e60c9090 Mon Sep 17 00:00:00 2001 From: James Hiebert Date: Wed, 11 Jun 2025 14:00:13 -0700 Subject: [PATCH 31/31] Use drop-in replacement for resource_filename --- tests/conftest.py | 12 ++++++++---- tests/mm_cataloguer/test_associate_ensemble.py | 14 +++++++------- tests/mm_cataloguer/test_index.py | 10 ++++++---- tests/modelmeta/test_against_test_sqlite_db.py | 9 +++++---- tests/test_helpers.py | 6 ++++++ 5 files changed, 32 insertions(+), 19 deletions(-) create mode 100644 tests/test_helpers.py diff --git a/tests/conftest.py b/tests/conftest.py index fc5168d..c89a618 100644 --- a/tests/conftest.py +++ b/tests/conftest.py @@ -23,9 +23,9 @@ factories, and sessions, one starting with databases with session scope, the other with databases with function scope. """ + import sys import os -from importlib.resources import files import datetime import time @@ -65,6 +65,8 @@ YCellBound, \ SpatialRefSys +from tests.test_helpers import resource_filename + # Add helpers directory to pythonpath: See https://stackoverflow.com/a/33515264 sys.path.append(os.path.join(os.path.dirname(__file__), 'helpers')) @@ -335,16 +337,18 @@ def test_session_with_empty_db_fs(test_session_factory_fs): # Database for migration testing -@pytest.fixture(scope='module') + +@pytest.fixture(scope="module") def db_uri(test_dsn): yield test_dsn # Parametrized fixtures + def open_tiny_dataset(abbrev): - filename = 'data/tiny_{}.nc'.format(abbrev) - return CFDataset((files("modelmeta") / filename).resolve()) + filename = "data/tiny_{}.nc".format(abbrev) + return CFDataset(resource_filename("modelmeta", filename)) # We parametrize these fixture so that every test that uses it is run for all diff --git a/tests/mm_cataloguer/test_associate_ensemble.py b/tests/mm_cataloguer/test_associate_ensemble.py index d79987e..5e889a9 100644 --- a/tests/mm_cataloguer/test_associate_ensemble.py +++ b/tests/mm_cataloguer/test_associate_ensemble.py @@ -1,7 +1,6 @@ """Test functions for associating an ensemble to a file. """ import pytest -from importlib.resources import files from nchelpers import CFDataset @@ -14,6 +13,7 @@ from mm_cataloguer.index_netcdf import \ index_cf_file, find_update_or_insert_cf_file +from tests.test_helpers import resource_filename from modelmeta import create_test_database from modelmeta import DataFile, DataFileVariable, \ @@ -34,7 +34,7 @@ def index_test_files(Session): 'data/tiny_hydromodel_gcm.nc', 'data/tiny_gcm_climo_monthly.nc', ] - filenames = [(files("modelmeta") / f).resolve() for f in test_files] + filenames = [resource_filename("modelmeta", f) for f in test_files] for filename in filenames: with CFDataset(filename) as cf: find_update_or_insert_cf_file(session, cf) @@ -155,10 +155,10 @@ def test_associate_ensemble_to_data_file__( # associate_ensemble_to_filepath -fp_gcm = (files('modelmeta') / 'data/tiny_gcm.nc').resolve() -fp_downscaled = (files('modelmeta') /'data/tiny_downscaled.nc').resolve() -fp_hydromodel_gcm = (files('modelmeta') / 'data/tiny_hydromodel_gcm.nc').resolve() -fp_gcm_climo_monthly = (files('modelmeta') / 'data/tiny_gcm_climo_monthly.nc').resolve() +fp_gcm = resource_filename('modelmeta', 'data/tiny_gcm.nc') +fp_downscaled = resource_filename('modelmeta', 'data/tiny_downscaled.nc') +fp_hydromodel_gcm = resource_filename('modelmeta', 'data/tiny_hydromodel_gcm.nc') +fp_gcm_climo_monthly = resource_filename('modelmeta', 'data/tiny_gcm_climo_monthly.nc') @pytest.mark.slow @pytest.mark.parametrize( @@ -228,7 +228,7 @@ def test_associate_ensemble_to_filepath__( 'data/tiny_gcm_climo_monthly.nc', ] fps = [ - [str((files('modelmeta') / f).resolve()) for f in files_to_associate[:number]] + [resource_filename('modelmeta', f) for f in files_to_associate[:number]] for number in [1,2,4] ] diff --git a/tests/mm_cataloguer/test_index.py b/tests/mm_cataloguer/test_index.py index 70cdfc7..9e08a29 100644 --- a/tests/mm_cataloguer/test_index.py +++ b/tests/mm_cataloguer/test_index.py @@ -25,7 +25,6 @@ import os import datetime -from importlib.resources import files import pytest from netCDF4 import date2num, num2date, chartostring @@ -60,12 +59,15 @@ insert_timeset, find_timeset, find_or_insert_timeset, \ get_grid_info, get_level_set_info, \ seconds_since_epoch, usable_name, wkt +from tests.test_helpers import resource_filename + from mock_helper import Mock # Helper functions for defining tests + def conditional(f, false_value=None): """Return a function that, dependent on an additional boolean keyword parameter ``invoke``, either invokes and returns the value of the argument @@ -1171,7 +1173,7 @@ def test_index_netcdf_file( create_test_database(test_engine_fs) # Index file - filepath = (files("modelmeta") / rel_filepath).resolve() + filepath = resource_filename("modelmeta", rel_filepath) data_file_id = index_netcdf_file(filepath, test_session_factory_fs) # Check results @@ -1198,7 +1200,7 @@ def test_index_netcdf_file_with_error( create_test_database(test_engine_fs) # Index file - filepath = str((files("modelmeta") / rel_filepath).resolve()) + filepath = resource_filename("modelmeta", rel_filepath) data_file_id = index_netcdf_file(filepath, test_session_factory_fs) # Check results @@ -1228,7 +1230,7 @@ def test_index_netcdf_files(test_dsn_fs, test_engine_fs): 'data/tiny_gcm_climo_yearly.nc', 'data/tiny_streamflow.nc', ] - filenames = [(files("modelmeta") / f).resolve() for f in test_files] + filenames = [resource_filename("modelmeta", f) for f in test_files] data_file_ids = index_netcdf_files(filenames, test_dsn_fs) # Check results diff --git a/tests/modelmeta/test_against_test_sqlite_db.py b/tests/modelmeta/test_against_test_sqlite_db.py index d1e694f..43f8aa5 100644 --- a/tests/modelmeta/test_against_test_sqlite_db.py +++ b/tests/modelmeta/test_against_test_sqlite_db.py @@ -1,15 +1,16 @@ -from importlib.resources import files - import modelmeta import pytest from sqlalchemy import create_engine from sqlalchemy.orm import sessionmaker +from tests.test_helpers import resource_filename + + @pytest.fixture def test_session(): - f = (files("modelmeta") / "data/mddb-v2.sqlite").resolve() - engine = create_engine('sqlite:///{0}'.format(f)) + f = resource_filename("modelmeta", "data/mddb-v2.sqlite") + engine = create_engine("sqlite:///{0}".format(f)) Session = sessionmaker(bind=engine) return Session() diff --git a/tests/test_helpers.py b/tests/test_helpers.py new file mode 100644 index 0000000..d24857b --- /dev/null +++ b/tests/test_helpers.py @@ -0,0 +1,6 @@ +from importlib import import_module +from importlib.resources import files + + +def resource_filename(package, path): + return str(files(import_module(package)) / path)