diff --git a/poetry.lock b/poetry.lock index 2ccb6ca..14a6773 100644 --- a/poetry.lock +++ b/poetry.lock @@ -1,5 +1,16 @@ # This file is automatically @generated by Poetry 1.8.2 and should not be changed by hand. +[[package]] +name = "annotated-types" +version = "0.7.0" +description = "Reusable constraint types to use with typing.Annotated" +optional = false +python-versions = ">=3.8" +files = [ + {file = "annotated_types-0.7.0-py3-none-any.whl", hash = "sha256:1f02e8b43a8fbbc3f3e0d4f0f4bfc8131bcb4eebe8849b8e5c773f3a1c582a53"}, + {file = "annotated_types-0.7.0.tar.gz", hash = "sha256:aff07c09a53a08bc8cfccb9c85b05f1aa9a2a6f23728d790723543408344ce89"}, +] + [[package]] name = "astroid" version = "2.15.8" @@ -67,13 +78,13 @@ uvloop = ["uvloop (>=0.15.2)"] [[package]] name = "certifi" -version = "2024.6.2" +version = "2024.7.4" description = "Python package for providing Mozilla's CA Bundle." optional = false python-versions = ">=3.6" files = [ - {file = "certifi-2024.6.2-py3-none-any.whl", hash = "sha256:ddc6c8ce995e6987e7faf5e3f1b02b302836a0e5d98ece18392cb1a36c72ad56"}, - {file = "certifi-2024.6.2.tar.gz", hash = "sha256:3cd43f1c6fa7dedc5899d69d3ad0398fd018ad1a17fba83ddaf78aa46c747516"}, + {file = "certifi-2024.7.4-py3-none-any.whl", hash = "sha256:c198e21b1289c2ab85ee4e67bb4b4ef3ead0892059901a8d5b622f24a1101e90"}, + {file = "certifi-2024.7.4.tar.gz", hash = "sha256:5a1e7645bc0ec61a09e26c36f6106dd4cf40c6db3a1fb6352b0244e7fb057c7b"}, ] [[package]] @@ -543,13 +554,13 @@ files = [ [[package]] name = "openpyxl" -version = "3.1.4" +version = "3.1.5" description = "A Python library to read/write Excel 2010 xlsx/xlsm files" optional = false python-versions = ">=3.8" files = [ - {file = "openpyxl-3.1.4-py2.py3-none-any.whl", hash = "sha256:ec17f6483f2b8f7c88c57e5e5d3b0de0e3fb9ac70edc084d28e864f5b33bbefd"}, - {file = "openpyxl-3.1.4.tar.gz", hash = "sha256:8d2c8adf5d20d6ce8f9bca381df86b534835e974ed0156dacefa76f68c1d69fb"}, + {file = "openpyxl-3.1.5-py2.py3-none-any.whl", hash = "sha256:5282c12b107bffeef825f4617dc029afaf41d0ea60823bbb665ef3079dc79de2"}, + {file = "openpyxl-3.1.5.tar.gz", hash = "sha256:cf0e3cf56142039133628b5acffe8ef0c12bc902d2aadd3e0fe5878dc08d1050"}, ] [package.dependencies] @@ -683,63 +694,145 @@ testing = ["pytest", "pytest-benchmark"] [[package]] name = "pydantic" -version = "1.10.17" -description = "Data validation and settings management using python type hints" +version = "2.8.2" +description = "Data validation using Python type hints" optional = false -python-versions = ">=3.7" +python-versions = ">=3.8" files = [ - {file = "pydantic-1.10.17-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:0fa51175313cc30097660b10eec8ca55ed08bfa07acbfe02f7a42f6c242e9a4b"}, - {file = "pydantic-1.10.17-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:c7e8988bb16988890c985bd2093df9dd731bfb9d5e0860db054c23034fab8f7a"}, - {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:371dcf1831f87c9e217e2b6a0c66842879a14873114ebb9d0861ab22e3b5bb1e"}, - {file = "pydantic-1.10.17-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4866a1579c0c3ca2c40575398a24d805d4db6cb353ee74df75ddeee3c657f9a7"}, - {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:543da3c6914795b37785703ffc74ba4d660418620cc273490d42c53949eeeca6"}, - {file = "pydantic-1.10.17-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:7623b59876f49e61c2e283551cc3647616d2fbdc0b4d36d3d638aae8547ea681"}, - {file = "pydantic-1.10.17-cp310-cp310-win_amd64.whl", hash = "sha256:409b2b36d7d7d19cd8310b97a4ce6b1755ef8bd45b9a2ec5ec2b124db0a0d8f3"}, - {file = "pydantic-1.10.17-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:fa43f362b46741df8f201bf3e7dff3569fa92069bcc7b4a740dea3602e27ab7a"}, - {file = "pydantic-1.10.17-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2a72d2a5ff86a3075ed81ca031eac86923d44bc5d42e719d585a8eb547bf0c9b"}, - {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b4ad32aed3bf5eea5ca5decc3d1bbc3d0ec5d4fbcd72a03cdad849458decbc63"}, - {file = "pydantic-1.10.17-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:aeb4e741782e236ee7dc1fb11ad94dc56aabaf02d21df0e79e0c21fe07c95741"}, - {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:d2f89a719411cb234105735a520b7c077158a81e0fe1cb05a79c01fc5eb59d3c"}, - {file = "pydantic-1.10.17-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:db3b48d9283d80a314f7a682f7acae8422386de659fffaba454b77a083c3937d"}, - {file = "pydantic-1.10.17-cp311-cp311-win_amd64.whl", hash = "sha256:9c803a5113cfab7bbb912f75faa4fc1e4acff43e452c82560349fff64f852e1b"}, - {file = "pydantic-1.10.17-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:820ae12a390c9cbb26bb44913c87fa2ff431a029a785642c1ff11fed0a095fcb"}, - {file = "pydantic-1.10.17-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:c1e51d1af306641b7d1574d6d3307eaa10a4991542ca324f0feb134fee259815"}, - {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9e53fb834aae96e7b0dadd6e92c66e7dd9cdf08965340ed04c16813102a47fab"}, - {file = "pydantic-1.10.17-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0e2495309b1266e81d259a570dd199916ff34f7f51f1b549a0d37a6d9b17b4dc"}, - {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_i686.whl", hash = "sha256:098ad8de840c92ea586bf8efd9e2e90c6339d33ab5c1cfbb85be66e4ecf8213f"}, - {file = "pydantic-1.10.17-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:525bbef620dac93c430d5d6bdbc91bdb5521698d434adf4434a7ef6ffd5c4b7f"}, - {file = "pydantic-1.10.17-cp312-cp312-win_amd64.whl", hash = "sha256:6654028d1144df451e1da69a670083c27117d493f16cf83da81e1e50edce72ad"}, - {file = "pydantic-1.10.17-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:c87cedb4680d1614f1d59d13fea353faf3afd41ba5c906a266f3f2e8c245d655"}, - {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:11289fa895bcbc8f18704efa1d8020bb9a86314da435348f59745473eb042e6b"}, - {file = "pydantic-1.10.17-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:94833612d6fd18b57c359a127cbfd932d9150c1b72fea7c86ab58c2a77edd7c7"}, - {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_i686.whl", hash = "sha256:d4ecb515fa7cb0e46e163ecd9d52f9147ba57bc3633dca0e586cdb7a232db9e3"}, - {file = "pydantic-1.10.17-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:7017971ffa7fd7808146880aa41b266e06c1e6e12261768a28b8b41ba55c8076"}, - {file = "pydantic-1.10.17-cp37-cp37m-win_amd64.whl", hash = "sha256:e840e6b2026920fc3f250ea8ebfdedf6ea7a25b77bf04c6576178e681942ae0f"}, - {file = "pydantic-1.10.17-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:bfbb18b616abc4df70591b8c1ff1b3eabd234ddcddb86b7cac82657ab9017e33"}, - {file = "pydantic-1.10.17-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:ebb249096d873593e014535ab07145498957091aa6ae92759a32d40cb9998e2e"}, - {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d8c209af63ccd7b22fba94b9024e8b7fd07feffee0001efae50dd99316b27768"}, - {file = "pydantic-1.10.17-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d4b40c9e13a0b61583e5599e7950490c700297b4a375b55b2b592774332798b7"}, - {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_i686.whl", hash = "sha256:c31d281c7485223caf6474fc2b7cf21456289dbaa31401844069b77160cab9c7"}, - {file = "pydantic-1.10.17-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:ae5184e99a060a5c80010a2d53c99aee76a3b0ad683d493e5f0620b5d86eeb75"}, - {file = "pydantic-1.10.17-cp38-cp38-win_amd64.whl", hash = "sha256:ad1e33dc6b9787a6f0f3fd132859aa75626528b49cc1f9e429cdacb2608ad5f0"}, - {file = "pydantic-1.10.17-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:7e17c0ee7192e54a10943f245dc79e36d9fe282418ea05b886e1c666063a7b54"}, - {file = "pydantic-1.10.17-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:cafb9c938f61d1b182dfc7d44a7021326547b7b9cf695db5b68ec7b590214773"}, - {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:95ef534e3c22e5abbdbdd6f66b6ea9dac3ca3e34c5c632894f8625d13d084cbe"}, - {file = "pydantic-1.10.17-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62d96b8799ae3d782df7ec9615cb59fc32c32e1ed6afa1b231b0595f6516e8ab"}, - {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:ab2f976336808fd5d539fdc26eb51f9aafc1f4b638e212ef6b6f05e753c8011d"}, - {file = "pydantic-1.10.17-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:b8ad363330557beac73159acfbeed220d5f1bfcd6b930302a987a375e02f74fd"}, - {file = "pydantic-1.10.17-cp39-cp39-win_amd64.whl", hash = "sha256:48db882e48575ce4b39659558b2f9f37c25b8d348e37a2b4e32971dd5a7d6227"}, - {file = "pydantic-1.10.17-py3-none-any.whl", hash = "sha256:e41b5b973e5c64f674b3b4720286ded184dcc26a691dd55f34391c62c6934688"}, - {file = "pydantic-1.10.17.tar.gz", hash = "sha256:f434160fb14b353caf634149baaf847206406471ba70e64657c1e8330277a991"}, + {file = "pydantic-2.8.2-py3-none-any.whl", hash = "sha256:73ee9fddd406dc318b885c7a2eab8a6472b68b8fb5ba8150949fc3db939f23c8"}, + {file = "pydantic-2.8.2.tar.gz", hash = "sha256:6f62c13d067b0755ad1c21a34bdd06c0c12625a22b0fc09c6b149816604f7c2a"}, ] [package.dependencies] -python-dotenv = {version = ">=0.10.4", optional = true, markers = "extra == \"dotenv\""} -typing-extensions = ">=4.2.0" +annotated-types = ">=0.4.0" +pydantic-core = "2.20.1" +typing-extensions = [ + {version = ">=4.6.1", markers = "python_version < \"3.13\""}, + {version = ">=4.12.2", markers = "python_version >= \"3.13\""}, +] [package.extras] -dotenv = ["python-dotenv (>=0.10.4)"] -email = ["email-validator (>=1.0.3)"] +email = ["email-validator (>=2.0.0)"] + +[[package]] +name = "pydantic-core" +version = "2.20.1" +description = "Core functionality for Pydantic validation and serialization" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_10_12_x86_64.whl", hash = "sha256:3acae97ffd19bf091c72df4d726d552c473f3576409b2a7ca36b2f535ffff4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:41f4c96227a67a013e7de5ff8f20fb496ce573893b7f4f2707d065907bffdbd6"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5f239eb799a2081495ea659d8d4a43a8f42cd1fe9ff2e7e436295c38a10c286a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:53e431da3fc53360db73eedf6f7124d1076e1b4ee4276b36fb25514544ceb4a3"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f1f62b2413c3a0e846c3b838b2ecd6c7a19ec6793b2a522745b0869e37ab5bc1"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5d41e6daee2813ecceea8eda38062d69e280b39df793f5a942fa515b8ed67953"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3d482efec8b7dc6bfaedc0f166b2ce349df0011f5d2f1f25537ced4cfc34fd98"}, + {file = "pydantic_core-2.20.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e93e1a4b4b33daed65d781a57a522ff153dcf748dee70b40c7258c5861e1768a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:e7c4ea22b6739b162c9ecaaa41d718dfad48a244909fe7ef4b54c0b530effc5a"}, + {file = "pydantic_core-2.20.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:4f2790949cf385d985a31984907fecb3896999329103df4e4983a4a41e13e840"}, + {file = "pydantic_core-2.20.1-cp310-none-win32.whl", hash = "sha256:5e999ba8dd90e93d57410c5e67ebb67ffcaadcea0ad973240fdfd3a135506250"}, + {file = "pydantic_core-2.20.1-cp310-none-win_amd64.whl", hash = "sha256:512ecfbefef6dac7bc5eaaf46177b2de58cdf7acac8793fe033b24ece0b9566c"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:d2a8fa9d6d6f891f3deec72f5cc668e6f66b188ab14bb1ab52422fe8e644f312"}, + {file = "pydantic_core-2.20.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:175873691124f3d0da55aeea1d90660a6ea7a3cfea137c38afa0a5ffabe37b88"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:37eee5b638f0e0dcd18d21f59b679686bbd18917b87db0193ae36f9c23c355fc"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:25e9185e2d06c16ee438ed39bf62935ec436474a6ac4f9358524220f1b236e43"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:150906b40ff188a3260cbee25380e7494ee85048584998c1e66df0c7a11c17a6"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8ad4aeb3e9a97286573c03df758fc7627aecdd02f1da04516a86dc159bf70121"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d3f3ed29cd9f978c604708511a1f9c2fdcb6c38b9aae36a51905b8811ee5cbf1"}, + {file = "pydantic_core-2.20.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:b0dae11d8f5ded51699c74d9548dcc5938e0804cc8298ec0aa0da95c21fff57b"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:faa6b09ee09433b87992fb5a2859efd1c264ddc37280d2dd5db502126d0e7f27"}, + {file = "pydantic_core-2.20.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:9dc1b507c12eb0481d071f3c1808f0529ad41dc415d0ca11f7ebfc666e66a18b"}, + {file = "pydantic_core-2.20.1-cp311-none-win32.whl", hash = "sha256:fa2fddcb7107e0d1808086ca306dcade7df60a13a6c347a7acf1ec139aa6789a"}, + {file = "pydantic_core-2.20.1-cp311-none-win_amd64.whl", hash = "sha256:40a783fb7ee353c50bd3853e626f15677ea527ae556429453685ae32280c19c2"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:595ba5be69b35777474fa07f80fc260ea71255656191adb22a8c53aba4479231"}, + {file = "pydantic_core-2.20.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:a4f55095ad087474999ee28d3398bae183a66be4823f753cd7d67dd0153427c9"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f9aa05d09ecf4c75157197f27cdc9cfaeb7c5f15021c6373932bf3e124af029f"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:e97fdf088d4b31ff4ba35db26d9cc472ac7ef4a2ff2badeabf8d727b3377fc52"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bc633a9fe1eb87e250b5c57d389cf28998e4292336926b0b6cdaee353f89a237"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:d573faf8eb7e6b1cbbcb4f5b247c60ca8be39fe2c674495df0eb4318303137fe"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:26dc97754b57d2fd00ac2b24dfa341abffc380b823211994c4efac7f13b9e90e"}, + {file = "pydantic_core-2.20.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:33499e85e739a4b60c9dac710c20a08dc73cb3240c9a0e22325e671b27b70d24"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bebb4d6715c814597f85297c332297c6ce81e29436125ca59d1159b07f423eb1"}, + {file = "pydantic_core-2.20.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:516d9227919612425c8ef1c9b869bbbee249bc91912c8aaffb66116c0b447ebd"}, + {file = "pydantic_core-2.20.1-cp312-none-win32.whl", hash = "sha256:469f29f9093c9d834432034d33f5fe45699e664f12a13bf38c04967ce233d688"}, + {file = "pydantic_core-2.20.1-cp312-none-win_amd64.whl", hash = "sha256:035ede2e16da7281041f0e626459bcae33ed998cca6a0a007a5ebb73414ac72d"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_10_12_x86_64.whl", hash = "sha256:0827505a5c87e8aa285dc31e9ec7f4a17c81a813d45f70b1d9164e03a813a686"}, + {file = "pydantic_core-2.20.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:19c0fa39fa154e7e0b7f82f88ef85faa2a4c23cc65aae2f5aea625e3c13c735a"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:4aa223cd1e36b642092c326d694d8bf59b71ddddc94cdb752bbbb1c5c91d833b"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:c336a6d235522a62fef872c6295a42ecb0c4e1d0f1a3e500fe949415761b8a19"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7eb6a0587eded33aeefea9f916899d42b1799b7b14b8f8ff2753c0ac1741edac"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:70c8daf4faca8da5a6d655f9af86faf6ec2e1768f4b8b9d0226c02f3d6209703"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e9fa4c9bf273ca41f940bceb86922a7667cd5bf90e95dbb157cbb8441008482c"}, + {file = "pydantic_core-2.20.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:11b71d67b4725e7e2a9f6e9c0ac1239bbc0c48cce3dc59f98635efc57d6dac83"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:270755f15174fb983890c49881e93f8f1b80f0b5e3a3cc1394a255706cabd203"}, + {file = "pydantic_core-2.20.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:c81131869240e3e568916ef4c307f8b99583efaa60a8112ef27a366eefba8ef0"}, + {file = "pydantic_core-2.20.1-cp313-none-win32.whl", hash = "sha256:b91ced227c41aa29c672814f50dbb05ec93536abf8f43cd14ec9521ea09afe4e"}, + {file = "pydantic_core-2.20.1-cp313-none-win_amd64.whl", hash = "sha256:65db0f2eefcaad1a3950f498aabb4875c8890438bc80b19362cf633b87a8ab20"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_10_12_x86_64.whl", hash = "sha256:4745f4ac52cc6686390c40eaa01d48b18997cb130833154801a442323cc78f91"}, + {file = "pydantic_core-2.20.1-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:a8ad4c766d3f33ba8fd692f9aa297c9058970530a32c728a2c4bfd2616d3358b"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:41e81317dd6a0127cabce83c0c9c3fbecceae981c8391e6f1dec88a77c8a569a"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:04024d270cf63f586ad41fff13fde4311c4fc13ea74676962c876d9577bcc78f"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:eaad4ff2de1c3823fddf82f41121bdf453d922e9a238642b1dedb33c4e4f98ad"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:26ab812fa0c845df815e506be30337e2df27e88399b985d0bb4e3ecfe72df31c"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3c5ebac750d9d5f2706654c638c041635c385596caf68f81342011ddfa1e5598"}, + {file = "pydantic_core-2.20.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2aafc5a503855ea5885559eae883978c9b6d8c8993d67766ee73d82e841300dd"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:4868f6bd7c9d98904b748a2653031fc9c2f85b6237009d475b1008bfaeb0a5aa"}, + {file = "pydantic_core-2.20.1-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:aa2f457b4af386254372dfa78a2eda2563680d982422641a85f271c859df1987"}, + {file = "pydantic_core-2.20.1-cp38-none-win32.whl", hash = "sha256:225b67a1f6d602de0ce7f6c1c3ae89a4aa25d3de9be857999e9124f15dab486a"}, + {file = "pydantic_core-2.20.1-cp38-none-win_amd64.whl", hash = "sha256:6b507132dcfc0dea440cce23ee2182c0ce7aba7054576efc65634f080dbe9434"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_10_12_x86_64.whl", hash = "sha256:b03f7941783b4c4a26051846dea594628b38f6940a2fdc0df00b221aed39314c"}, + {file = "pydantic_core-2.20.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:1eedfeb6089ed3fad42e81a67755846ad4dcc14d73698c120a82e4ccf0f1f9f6"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:635fee4e041ab9c479e31edda27fcf966ea9614fff1317e280d99eb3e5ab6fe2"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:77bf3ac639c1ff567ae3b47f8d4cc3dc20f9966a2a6dd2311dcc055d3d04fb8a"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:7ed1b0132f24beeec5a78b67d9388656d03e6a7c837394f99257e2d55b461611"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c6514f963b023aeee506678a1cf821fe31159b925c4b76fe2afa94cc70b3222b"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:10d4204d8ca33146e761c79f83cc861df20e7ae9f6487ca290a97702daf56006"}, + {file = "pydantic_core-2.20.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:2d036c7187b9422ae5b262badb87a20a49eb6c5238b2004e96d4da1231badef1"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9ebfef07dbe1d93efb94b4700f2d278494e9162565a54f124c404a5656d7ff09"}, + {file = "pydantic_core-2.20.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:6b9d9bb600328a1ce523ab4f454859e9d439150abb0906c5a1983c146580ebab"}, + {file = "pydantic_core-2.20.1-cp39-none-win32.whl", hash = "sha256:784c1214cb6dd1e3b15dd8b91b9a53852aed16671cc3fbe4786f4f1db07089e2"}, + {file = "pydantic_core-2.20.1-cp39-none-win_amd64.whl", hash = "sha256:d2fe69c5434391727efa54b47a1e7986bb0186e72a41b203df8f5b0a19a4f669"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_10_12_x86_64.whl", hash = "sha256:a45f84b09ac9c3d35dfcf6a27fd0634d30d183205230a0ebe8373a0e8cfa0906"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-macosx_11_0_arm64.whl", hash = "sha256:d02a72df14dfdbaf228424573a07af10637bd490f0901cee872c4f434a735b94"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2b27e6af28f07e2f195552b37d7d66b150adbaa39a6d327766ffd695799780f"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:084659fac3c83fd674596612aeff6041a18402f1e1bc19ca39e417d554468482"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:242b8feb3c493ab78be289c034a1f659e8826e2233786e36f2893a950a719bb6"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:38cf1c40a921d05c5edc61a785c0ddb4bed67827069f535d794ce6bcded919fc"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:e0bbdd76ce9aa5d4209d65f2b27fc6e5ef1312ae6c5333c26db3f5ade53a1e99"}, + {file = "pydantic_core-2.20.1-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:254ec27fdb5b1ee60684f91683be95e5133c994cc54e86a0b0963afa25c8f8a6"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_10_12_x86_64.whl", hash = "sha256:407653af5617f0757261ae249d3fba09504d7a71ab36ac057c938572d1bc9331"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-macosx_11_0_arm64.whl", hash = "sha256:c693e916709c2465b02ca0ad7b387c4f8423d1db7b4649c551f27a529181c5ad"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5b5ff4911aea936a47d9376fd3ab17e970cc543d1b68921886e7f64bd28308d1"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:177f55a886d74f1808763976ac4efd29b7ed15c69f4d838bbd74d9d09cf6fa86"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:964faa8a861d2664f0c7ab0c181af0bea66098b1919439815ca8803ef136fc4e"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:4dd484681c15e6b9a977c785a345d3e378d72678fd5f1f3c0509608da24f2ac0"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:f6d6cff3538391e8486a431569b77921adfcdef14eb18fbf19b7c0a5294d4e6a"}, + {file = "pydantic_core-2.20.1-pp39-pypy39_pp73-win_amd64.whl", hash = "sha256:a6d511cc297ff0883bc3708b465ff82d7560193169a8b93260f74ecb0a5e08a7"}, + {file = "pydantic_core-2.20.1.tar.gz", hash = "sha256:26ca695eeee5f9f1aeeb211ffc12f10bcb6f71e2989988fda61dabd65db878d4"}, +] + +[package.dependencies] +typing-extensions = ">=4.6.0,<4.7.0 || >4.7.0" + +[[package]] +name = "pydantic-settings" +version = "2.3.4" +description = "Settings management using Pydantic" +optional = false +python-versions = ">=3.8" +files = [ + {file = "pydantic_settings-2.3.4-py3-none-any.whl", hash = "sha256:11ad8bacb68a045f00e4f862c7a718c8a9ec766aa8fd4c32e39a0594b207b53a"}, + {file = "pydantic_settings-2.3.4.tar.gz", hash = "sha256:c5802e3d62b78e82522319bbc9b8f8ffb28ad1c988a99311d04f2a6051fca0a7"}, +] + +[package.dependencies] +pydantic = ">=2.7.0" +python-dotenv = ">=0.21.0" + +[package.extras] +toml = ["tomli (>=2.0.1)"] +yaml = ["pyyaml (>=6.0.1)"] [[package]] name = "pydocstyle" @@ -1096,4 +1189,4 @@ files = [ [metadata] lock-version = "2.0" python-versions = "^3.9" -content-hash = "3ec292f6721e165564d7165a8670e20b1987176da52723ffaa2e0af9704e5f93" +content-hash = "0397ccd314f36faa8f2609d87300fa8770a7e3d8339761adc964a07a4b8e0f3d" diff --git a/pyproject.toml b/pyproject.toml index 0e241f2..4488a5c 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -1,6 +1,6 @@ [tool.poetry] name = "geneweaver-core" -version = "0.10.0a2" +version = "0.10.0a3" description = "The core of the Jax-Geneweaver Python library" authors = ["Jax Computational Sciences "] readme = "README.md" @@ -13,11 +13,12 @@ packages = [ [tool.poetry.dependencies] python = "^3.9" -pydantic = { extras = ["dotenv"], version = "^1.10" } +pydantic = { extras = ["dotenv"], version = "^2.8" } openpyxl = "^3.1.2" numpy = ">=1.22,<2" pandas = ">=1.5,<3" requests = "^2.32.0" +pydantic-settings = "^2.3.4" [tool.poetry.group.dev.dependencies] pylint = "^2.15.4" @@ -26,6 +27,7 @@ pydocstyle = "^6.1.1" pytest-cov = "^4.0.0" geneweaver-testing = "^0.1.0" + [tool.ruff] select = ['F', 'E', 'W', 'A', 'C90', 'N', 'B', 'ANN', 'D', 'I', 'ERA', 'PD', 'NPY', 'PT'] diff --git a/src/geneweaver/core/config_class.py b/src/geneweaver/core/config_class.py index e237497..55212ae 100644 --- a/src/geneweaver/core/config_class.py +++ b/src/geneweaver/core/config_class.py @@ -4,24 +4,23 @@ https://pydantic-docs.helpmanual.io/usage/settings/ """ -from pydantic import BaseSettings +from pydantic_settings import BaseSettings, SettingsConfigDict class ExternalServiceSettings(BaseSettings): """External Service Config and Settings Configuration.""" - PUBMED_XLM_SVC_URL = "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id={0}&retmode=xml" + PUBMED_XLM_SVC_URL: str = ( + "https://eutils.ncbi.nlm.nih.gov/entrez/eutils/efetch.fcgi?db=pubmed&id={0}&retmode=xml" + ) class CoreSettings(BaseSettings): """Root Config and Settings Configuration.""" - PROJECT_NAME = "jax-geneweaver-core" - VERSION = "0.0.2" + PROJECT_NAME: str = "jax-geneweaver-core" + VERSION: str = "0.0.2" LOG_LEVEL: str = "INFO" SERVICE_URLS: ExternalServiceSettings = ExternalServiceSettings() - class Config: - """Pydantic Config class.""" - - env_prefix = "GW_" + model_config = SettingsConfigDict(env_prefix="GW_") diff --git a/src/geneweaver/core/enum.py b/src/geneweaver/core/enum.py index 1b3e0f6..cb9db5e 100644 --- a/src/geneweaver/core/enum.py +++ b/src/geneweaver/core/enum.py @@ -223,6 +223,8 @@ class Species(_StrToIntMixin, Enum): SACCHAROMYCES_CEREVISIAE = "Saccharomyces Cerevisiae" GALLUS_GALLUS = "Gallus Gallus" CANIS_FAMILIARIS = "Canis Familiaris" + XENOPUS_TROPICALIS = "Xenopus Tropicalis" + XENOPUS_LAEVIS = "Xenopus Laevis" @staticmethod def _int_class() -> Enum: @@ -243,6 +245,8 @@ class SpeciesInt(_IntToStrMixin, IntEnum): SACCHAROMYCES_CEREVISIAE = 9 GALLUS_GALLUS = 10 CANIS_FAMILIARIS = 11 + XENOPUS_TROPICALIS = 12 + XENOPUS_LAEVIS = 13 @staticmethod def _str_class() -> Enum: diff --git a/src/geneweaver/core/schema/batch.py b/src/geneweaver/core/schema/batch.py index 4daa52e..da27f20 100644 --- a/src/geneweaver/core/schema/batch.py +++ b/src/geneweaver/core/schema/batch.py @@ -1,14 +1,15 @@ """Module for defining schemas for batch endpoints.""" -# ruff: noqa: N805, ANN001, ANN101 -from typing import List, Optional, Union +# ruff: noqa: N805, ANN001, ANN101, ANN401 +from typing import Any, List, Optional, Type, Union from geneweaver.core.enum import GeneIdentifierInt, MicroarrayInt, SpeciesInt from geneweaver.core.parse.score import parse_score from geneweaver.core.schema.gene import GeneValue from geneweaver.core.schema.messages import MessageResponse from geneweaver.core.schema.score import GenesetScoreType -from pydantic import BaseModel, validator +from pydantic import BaseModel, field_validator, model_validator +from typing_extensions import Self # Header characters which DO NOT need to be space separated. HEADER_CHARACTERS = { @@ -86,8 +87,9 @@ class BatchUploadGeneset(BaseModel): description: str = "" values: List[GeneValue] - @validator("species", pre=True) - def initialize_species(cls, v) -> SpeciesInt: + @field_validator("species", mode="before") + @classmethod + def initialize_species(cls: Type["BatchUploadGeneset"], v: Any) -> SpeciesInt: """Initialize species.""" if isinstance(v, SpeciesInt): return v @@ -95,8 +97,11 @@ def initialize_species(cls, v) -> SpeciesInt: return SpeciesInt[v.replace(" ", "_").upper()] return SpeciesInt(v) - @validator("gene_id_type", pre=True) - def initialize_gene_id_type(cls, v) -> Union[GeneIdentifierInt, MicroarrayInt]: + @field_validator("gene_id_type", mode="before") + @classmethod + def initialize_gene_id_type( + cls: Type["BatchUploadGeneset"], v: Any + ) -> Union[GeneIdentifierInt, MicroarrayInt]: """Initialize gene id type.""" if isinstance(v, GeneIdentifierInt) or isinstance(v, MicroarrayInt): return v @@ -111,8 +116,9 @@ def initialize_gene_id_type(cls, v) -> Union[GeneIdentifierInt, MicroarrayInt]: ] return MicroarrayInt(v) - @validator("score", pre=True) - def initialize_score(cls, v) -> GenesetScoreType: + @field_validator("score", mode="before") + @classmethod + def initialize_score(cls: Type["BatchUploadGeneset"], v: Any) -> GenesetScoreType: """Initialize score type.""" if isinstance(v, GenesetScoreType): return v @@ -120,20 +126,21 @@ def initialize_score(cls, v) -> GenesetScoreType: return GenesetScoreType(**v) return parse_score(v) - @validator("private", pre=True) - def private_to_bool(cls, v) -> bool: + @field_validator("private", mode="before") + @classmethod + def private_to_bool(cls: Type["BatchUploadGeneset"], v: Any) -> bool: """Convert private str to bool.""" if isinstance(v, bool): return v return v.lower() != "public" - @validator("curation_id", pre=True) - def curation_id_to_int(cls, v, values) -> int: + @model_validator(mode="after") + def curation_id_to_int(self) -> Self: """Initialize curation id based on `private` value.""" - if not v: + if not self.curation_id: # If the geneset is private, it should be set to have # curation tier 5, otherwise it should be set to have # curation tier 4. # It should default to private if not specified. - return 5 if values.get("private", True) else 4 - return v + self.curation_id = 5 if self.private else 4 + return self diff --git a/src/geneweaver/core/schema/gene.py b/src/geneweaver/core/schema/gene.py index 4513ae6..c02304b 100644 --- a/src/geneweaver/core/schema/gene.py +++ b/src/geneweaver/core/schema/gene.py @@ -4,7 +4,7 @@ from typing import Any, List, Optional from geneweaver.core.enum import GeneIdentifier, Species -from pydantic import BaseModel +from pydantic import BaseModel, ConfigDict class Gene(BaseModel): @@ -26,8 +26,8 @@ class GeneRow(BaseModel): gdb_id: int sp_id: int ode_pref: bool - ode_date: Optional[str] - old_ode_gene_ids: Optional[List[int]] + ode_date: Optional[str] = None + old_ode_gene_ids: Optional[List[int]] = None class GeneValue(BaseModel): @@ -35,11 +35,7 @@ class GeneValue(BaseModel): symbol: str value: float - - class Config: - """Pydantic config.""" - - allow_mutation = False + model_config = ConfigDict(frozen=True) def __str__(self: "GeneValue") -> str: """Return the gene symbol.""" @@ -76,4 +72,4 @@ class GeneDatabaseRow(BaseModel): gdb_shortname: str gdb_date: str gdb_precision: int - gdb_linkout_url: Optional[str] + gdb_linkout_url: Optional[str] = None diff --git a/src/geneweaver/core/schema/legacy_api.py b/src/geneweaver/core/schema/legacy_api.py index d35ef44..d190f93 100644 --- a/src/geneweaver/core/schema/legacy_api.py +++ b/src/geneweaver/core/schema/legacy_api.py @@ -3,20 +3,20 @@ from typing import List, Optional from geneweaver.core.enum import GenesetAccess, ScoreType -from pydantic import BaseModel, HttpUrl +from pydantic import BaseModel, ConfigDict, HttpUrl class AddGenesetByUserPublication(BaseModel): """Publication schema for adding genesets by user.""" - pub_abstract: Optional[str] - pub_authors: Optional[str] - pub_journal: Optional[str] - pub_pages: Optional[str] - pub_pubmed: Optional[str] - pub_title: Optional[str] - pub_volume: Optional[str] - pub_year: Optional[str] + pub_abstract: Optional[str] = None + pub_authors: Optional[str] = None + pub_journal: Optional[str] = None + pub_pages: Optional[str] = None + pub_pubmed: Optional[str] = None + pub_title: Optional[str] = None + pub_volume: Optional[str] = None + pub_year: Optional[str] = None class AddGenesetByUserBase(BaseModel): @@ -28,14 +28,10 @@ class AddGenesetByUserBase(BaseModel): gs_name: str gs_threshold_type: ScoreType permissions: GenesetAccess - publication: Optional[AddGenesetByUserPublication] + publication: Optional[AddGenesetByUserPublication] = None select_groups: List[str] sp_id: str - - class Config: - """Pydantic config.""" - - use_enum_values = True + model_config = ConfigDict(use_enum_values=True) class AddGenesetByUser(AddGenesetByUserBase): diff --git a/src/geneweaver/core/schema/score.py b/src/geneweaver/core/schema/score.py index d2e1daa..90a6b13 100644 --- a/src/geneweaver/core/schema/score.py +++ b/src/geneweaver/core/schema/score.py @@ -5,7 +5,8 @@ from typing import Optional from geneweaver.core.enum import ScoreType -from pydantic import BaseModel, validator +from pydantic import BaseModel, model_validator +from typing_extensions import Self class GenesetScoreType(BaseModel): @@ -29,21 +30,17 @@ def threshold_as_db_string(self) -> str: else: return str(self.threshold) - @validator("threshold_low") - def threshold_low_must_be_less_than_threshold( - cls, v: Optional[float], values: dict - ) -> Optional[float]: + @model_validator(mode="after") + def threshold_low_must_be_less_than_threshold(self) -> Self: """Threshold low must be less than threshold.""" - if v is not None and v > values.get("threshold"): + if self.threshold_low is not None and self.threshold_low > self.threshold: raise ValueError("threshold_low must be less than threshold") - return v + return self - @validator("threshold_low") - def threshold_low_correlation_and_effect_only( - cls, v: Optional[float], values: dict - ) -> Optional[float]: + @model_validator(mode="after") + def threshold_low_correlation_and_effect_only(self) -> Self: """Threshold low should only be set for correlation and effect score types.""" - if v is not None and values.get("score_type") not in [ + if self.threshold_low is not None and self.score_type not in [ ScoreType.CORRELATION, ScoreType.EFFECT, ]: @@ -51,4 +48,4 @@ def threshold_low_correlation_and_effect_only( "threshold_low should only be set for " "correlation and effect score types" ) - return v + return self diff --git a/src/geneweaver/core/schema/species.py b/src/geneweaver/core/schema/species.py index e4563a7..b929258 100644 --- a/src/geneweaver/core/schema/species.py +++ b/src/geneweaver/core/schema/species.py @@ -13,7 +13,7 @@ class Species(BaseModel): id: int # noqa: A003 name: str taxonomic_id: int - reference_gene_identifier: Optional[GeneIdentifier] + reference_gene_identifier: Optional[GeneIdentifier] = None class SpeciesRow(BaseModel): @@ -22,7 +22,7 @@ class SpeciesRow(BaseModel): sp_id: int sp_name: str sp_taxid: int - sp_ref_gdb_id: Optional[int] + sp_ref_gdb_id: Optional[int] = None sp_date: datetime.date - sp_biomart_info: Optional[str] + sp_biomart_info: Optional[str] = None sp_source_data: Json[Any] diff --git a/tests/unit/conftest.py b/tests/unit/conftest.py index 6921725..fd9580c 100644 --- a/tests/unit/conftest.py +++ b/tests/unit/conftest.py @@ -13,18 +13,22 @@ @pytest.fixture(scope="session") def core_settings_fields() -> List[str]: """Return a list of the pydantic Settings class fields.""" - return [field.name for field in CoreSettings.__fields__.values()] + return [name for name in CoreSettings.model_fields.keys()] @pytest.fixture(scope="session") def core_settings_required_fields() -> List[str]: """Return a list of the pydantic Settings class fields.""" - return [field.name for field in CoreSettings.__fields__.values() if field.required] + return [ + name for name, field in CoreSettings.model_fields.items() if field.is_required() + ] @pytest.fixture(scope="session") def core_settings_optional_fields() -> Dict[str, Any]: """Return a dict of the optional pydantic Settings class fields.""" return { - f.name: f.default for f in CoreSettings.__fields__.values() if not f.required + name: field.default + for name, field in CoreSettings.model_fields.items() + if not field.is_required() } diff --git a/tests/unit/publication/pubmed/test_get_publication.py b/tests/unit/publication/pubmed/test_get_publication.py index 5102116..6574b9e 100644 --- a/tests/unit/publication/pubmed/test_get_publication.py +++ b/tests/unit/publication/pubmed/test_get_publication.py @@ -128,7 +128,7 @@ def test_get_publication( result = get_publication(pubmed_id) - assert result.dict() == expected.dict() + assert result.model_dump() == expected.model_dump() mock_get_xml_for_pubmed_id.assert_called_once_with(pubmed_id) mock_extract_fields.assert_called_once() diff --git a/tests/unit/render/batch/test_format_genest_metadata.py b/tests/unit/render/batch/test_format_genest_metadata.py index ebee746..a3f8f53 100644 --- a/tests/unit/render/batch/test_format_genest_metadata.py +++ b/tests/unit/render/batch/test_format_genest_metadata.py @@ -11,6 +11,6 @@ def test_format_geneset_metadata_standard(mock_batch_upload_geneset_all_combinat # Assert that the output is a string and has the expected structure assert isinstance(formatted_metadata, str) # Additional assertions can be made based on the specific format of the metadata - assert formatted_metadata.count("\n") == 8 + assert formatted_metadata.count("\n") == 9 for char in ["!", "@", "%", "A", ":", "=", "+"]: assert char in formatted_metadata diff --git a/tests/unit/schema/legacy/test_legacy_schema_create.py b/tests/unit/schema/legacy/test_legacy_schema_create.py index 680ef2d..8f3b872 100644 --- a/tests/unit/schema/legacy/test_legacy_schema_create.py +++ b/tests/unit/schema/legacy/test_legacy_schema_create.py @@ -6,6 +6,7 @@ AddGenesetByUserFile, AddGenesetByUserPublication, ) +from pydantic.networks import AnyUrl def test_add_gs_by_user_pub_schema(add_geneset_by_user_publication_data: dict) -> None: @@ -44,4 +45,5 @@ def test_add_gs_by_user_file_schema(add_geneset_by_user_file_data: dict) -> None """Test the AddGenesetByUserFile class.""" gs = AddGenesetByUserFile(**add_geneset_by_user_file_data) _shared_add_gs_by_user_asserts(gs, add_geneset_by_user_file_data) - assert gs.file_url == add_geneset_by_user_file_data["file_url"] + assert gs.file_url == AnyUrl(add_geneset_by_user_file_data["file_url"]) + assert str(gs.file_url) == add_geneset_by_user_file_data["file_url"] + "/" diff --git a/tests/unit/schema/test_api_response_schemas.py b/tests/unit/schema/test_api_response_schemas.py index 66f610d..21d6229 100644 --- a/tests/unit/schema/test_api_response_schemas.py +++ b/tests/unit/schema/test_api_response_schemas.py @@ -7,6 +7,7 @@ from geneweaver.core.schema.gene import Gene, GeneValue from geneweaver.core.schema.geneset import BatchUpload, Geneset, GenesetTier from geneweaver.core.schema.publication import Publication, PublicationInfo +from pydantic import AnyUrl def test_paging_links(): @@ -17,10 +18,10 @@ def test_paging_links(): next="http://example.com/next", last="http://example.com/last", ) - assert links.first == "http://example.com/first" - assert links.previous == "http://example.com/previous" - assert links.next == "http://example.com/next" - assert links.last == "http://example.com/last" + assert str(links.first) == "http://example.com/first" + assert str(links.previous) == "http://example.com/previous" + assert str(links.next) == "http://example.com/next" + assert str(links.last) == "http://example.com/last" @pytest.mark.parametrize( @@ -65,10 +66,14 @@ def test_paging(): assert paging.items == 10 assert paging.total_pages == 5 assert paging.total_items == 50 - assert paging.links.first == "http://example.com/first" - assert paging.links.previous == "http://example.com/previous" - assert paging.links.next == "http://example.com/next" - assert paging.links.last == "http://example.com/last" + assert paging.links.first == AnyUrl("http://example.com/first") + assert paging.links.previous == AnyUrl("http://example.com/previous") + assert paging.links.next == AnyUrl("http://example.com/next") + assert paging.links.last == AnyUrl("http://example.com/last") + assert str(paging.links.first) == "http://example.com/first" + assert str(paging.links.previous) == "http://example.com/previous" + assert str(paging.links.next) == "http://example.com/next" + assert str(paging.links.last) == "http://example.com/last" @pytest.mark.parametrize( @@ -116,10 +121,18 @@ def test_collection_response(): assert collection_response.paging.items == 10 assert collection_response.paging.total_pages == 5 assert collection_response.paging.total_items == 50 - assert collection_response.paging.links.first == "http://example.com/first" - assert collection_response.paging.links.previous == "http://example.com/previous" - assert collection_response.paging.links.next == "http://example.com/next" - assert collection_response.paging.links.last == "http://example.com/last" + assert collection_response.paging.links.first == AnyUrl("http://example.com/first") + assert collection_response.paging.links.previous == AnyUrl( + "http://example.com/previous" + ) + assert collection_response.paging.links.next == AnyUrl("http://example.com/next") + assert collection_response.paging.links.last == AnyUrl("http://example.com/last") + assert str(collection_response.paging.links.first) == "http://example.com/first" + assert ( + str(collection_response.paging.links.previous) == "http://example.com/previous" + ) + assert str(collection_response.paging.links.next) == "http://example.com/next" + assert str(collection_response.paging.links.last) == "http://example.com/last" @pytest.mark.parametrize( diff --git a/tests/unit/test_config.py b/tests/unit/test_config.py index 835632d..0284a02 100644 --- a/tests/unit/test_config.py +++ b/tests/unit/test_config.py @@ -9,7 +9,7 @@ @pytest.mark.parametrize("attribute", ["PROJECT_NAME", "LOG_LEVEL"]) def test_core_settings_schema(attribute: List[str]) -> None: """Test the CoreSettings class.""" - schema = CoreSettings.schema() + schema = CoreSettings.model_json_schema() assert attribute in schema["properties"]