diff --git a/apps/api/poetry.lock b/apps/api/poetry.lock index c488cff2..c234a402 100644 --- a/apps/api/poetry.lock +++ b/apps/api/poetry.lock @@ -2840,112 +2840,105 @@ files = [ [[package]] name = "sqlalchemy" -version = "1.4.52" +version = "2.0.29" 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" files = [ - {file = "SQLAlchemy-1.4.52-cp310-cp310-macosx_11_0_x86_64.whl", hash = "sha256:f68016f9a5713684c1507cc37133c28035f29925c75c0df2f9d0f7571e23720a"}, - {file = "SQLAlchemy-1.4.52-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:24bb0f81fbbb13d737b7f76d1821ec0b117ce8cbb8ee5e8641ad2de41aa916d3"}, - {file = "SQLAlchemy-1.4.52-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e93983cc0d2edae253b3f2141b0a3fb07e41c76cd79c2ad743fc27eb79c3f6db"}, - {file = "SQLAlchemy-1.4.52-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:84e10772cfc333eb08d0b7ef808cd76e4a9a30a725fb62a0495877a57ee41d81"}, - {file = "SQLAlchemy-1.4.52-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:427988398d2902de042093d17f2b9619a5ebc605bf6372f7d70e29bde6736842"}, - {file = "SQLAlchemy-1.4.52-cp310-cp310-win32.whl", hash = "sha256:1296f2cdd6db09b98ceb3c93025f0da4835303b8ac46c15c2136e27ee4d18d94"}, - {file = "SQLAlchemy-1.4.52-cp310-cp310-win_amd64.whl", hash = "sha256:80e7f697bccc56ac6eac9e2df5c98b47de57e7006d2e46e1a3c17c546254f6ef"}, - {file = "SQLAlchemy-1.4.52-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2f251af4c75a675ea42766880ff430ac33291c8d0057acca79710f9e5a77383d"}, - {file = "SQLAlchemy-1.4.52-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:cb8f9e4c4718f111d7b530c4e6fb4d28f9f110eb82e7961412955b3875b66de0"}, - {file = "SQLAlchemy-1.4.52-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:afb1672b57f58c0318ad2cff80b384e816735ffc7e848d8aa51e0b0fc2f4b7bb"}, - {file = "SQLAlchemy-1.4.52-cp311-cp311-win32.whl", hash = "sha256:6e41cb5cda641f3754568d2ed8962f772a7f2b59403b95c60c89f3e0bd25f15e"}, - {file = "SQLAlchemy-1.4.52-cp311-cp311-win_amd64.whl", hash = "sha256:5bed4f8c3b69779de9d99eb03fd9ab67a850d74ab0243d1be9d4080e77b6af12"}, - {file = "SQLAlchemy-1.4.52-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:49e3772eb3380ac88d35495843daf3c03f094b713e66c7d017e322144a5c6b7c"}, - {file = "SQLAlchemy-1.4.52-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:618827c1a1c243d2540314c6e100aee7af09a709bd005bae971686fab6723554"}, - {file = "SQLAlchemy-1.4.52-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:de9acf369aaadb71a725b7e83a5ef40ca3de1cf4cdc93fa847df6b12d3cd924b"}, - {file = "SQLAlchemy-1.4.52-cp312-cp312-win32.whl", hash = "sha256:763bd97c4ebc74136ecf3526b34808c58945023a59927b416acebcd68d1fc126"}, - {file = "SQLAlchemy-1.4.52-cp312-cp312-win_amd64.whl", hash = "sha256:f12aaf94f4d9679ca475975578739e12cc5b461172e04d66f7a3c39dd14ffc64"}, - {file = "SQLAlchemy-1.4.52-cp36-cp36m-macosx_10_14_x86_64.whl", hash = "sha256:853fcfd1f54224ea7aabcf34b227d2b64a08cbac116ecf376907968b29b8e763"}, - {file = "SQLAlchemy-1.4.52-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:f98dbb8fcc6d1c03ae8ec735d3c62110949a3b8bc6e215053aa27096857afb45"}, - {file = "SQLAlchemy-1.4.52-cp36-cp36m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1e135fff2e84103bc15c07edd8569612ce317d64bdb391f49ce57124a73f45c5"}, - {file = "SQLAlchemy-1.4.52-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:5b5de6af8852500d01398f5047d62ca3431d1e29a331d0b56c3e14cb03f8094c"}, - {file = "SQLAlchemy-1.4.52-cp36-cp36m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:3491c85df263a5c2157c594f54a1a9c72265b75d3777e61ee13c556d9e43ffc9"}, - {file = "SQLAlchemy-1.4.52-cp36-cp36m-win32.whl", hash = "sha256:427c282dd0deba1f07bcbf499cbcc9fe9a626743f5d4989bfdfd3ed3513003dd"}, - {file = "SQLAlchemy-1.4.52-cp36-cp36m-win_amd64.whl", hash = "sha256:ca5ce82b11731492204cff8845c5e8ca1a4bd1ade85e3b8fcf86e7601bfc6a39"}, - {file = "SQLAlchemy-1.4.52-cp37-cp37m-macosx_11_0_x86_64.whl", hash = "sha256:29d4247313abb2015f8979137fe65f4eaceead5247d39603cc4b4a610936cd2b"}, - {file = "SQLAlchemy-1.4.52-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:a752bff4796bf22803d052d4841ebc3c55c26fb65551f2c96e90ac7c62be763a"}, - {file = "SQLAlchemy-1.4.52-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f7ea11727feb2861deaa293c7971a4df57ef1c90e42cb53f0da40c3468388000"}, - {file = "SQLAlchemy-1.4.52-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:d913f8953e098ca931ad7f58797f91deed26b435ec3756478b75c608aa80d139"}, - {file = "SQLAlchemy-1.4.52-cp37-cp37m-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a251146b921725547ea1735b060a11e1be705017b568c9f8067ca61e6ef85f20"}, - {file = "SQLAlchemy-1.4.52-cp37-cp37m-win32.whl", hash = "sha256:1f8e1c6a6b7f8e9407ad9afc0ea41c1f65225ce505b79bc0342159de9c890782"}, - {file = "SQLAlchemy-1.4.52-cp37-cp37m-win_amd64.whl", hash = "sha256:346ed50cb2c30f5d7a03d888e25744154ceac6f0e6e1ab3bc7b5b77138d37710"}, - {file = "SQLAlchemy-1.4.52-cp38-cp38-macosx_11_0_x86_64.whl", hash = "sha256:4dae6001457d4497736e3bc422165f107ecdd70b0d651fab7f731276e8b9e12d"}, - {file = "SQLAlchemy-1.4.52-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:a5d2e08d79f5bf250afb4a61426b41026e448da446b55e4770c2afdc1e200fce"}, - {file = "SQLAlchemy-1.4.52-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bbce5dd7c7735e01d24f5a60177f3e589078f83c8a29e124a6521b76d825b85"}, - {file = "SQLAlchemy-1.4.52-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:bdb7b4d889631a3b2a81a3347c4c3f031812eb4adeaa3ee4e6b0d028ad1852b5"}, - {file = "SQLAlchemy-1.4.52-cp38-cp38-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c294ae4e6bbd060dd79e2bd5bba8b6274d08ffd65b58d106394cb6abbf35cf45"}, - {file = "SQLAlchemy-1.4.52-cp38-cp38-win32.whl", hash = "sha256:bcdfb4b47fe04967669874fb1ce782a006756fdbebe7263f6a000e1db969120e"}, - {file = "SQLAlchemy-1.4.52-cp38-cp38-win_amd64.whl", hash = "sha256:7d0dbc56cb6af5088f3658982d3d8c1d6a82691f31f7b0da682c7b98fa914e91"}, - {file = "SQLAlchemy-1.4.52-cp39-cp39-macosx_11_0_x86_64.whl", hash = "sha256:a551d5f3dc63f096ed41775ceec72fdf91462bb95abdc179010dc95a93957800"}, - {file = "SQLAlchemy-1.4.52-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:6ab773f9ad848118df7a9bbabca53e3f1002387cdbb6ee81693db808b82aaab0"}, - {file = "SQLAlchemy-1.4.52-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d2de46f5d5396d5331127cfa71f837cca945f9a2b04f7cb5a01949cf676db7d1"}, - {file = "SQLAlchemy-1.4.52-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_12_x86_64.manylinux2010_x86_64.whl", hash = "sha256:7027be7930a90d18a386b25ee8af30514c61f3852c7268899f23fdfbd3107181"}, - {file = "SQLAlchemy-1.4.52-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:99224d621affbb3c1a4f72b631f8393045f4ce647dd3262f12fe3576918f8bf3"}, - {file = "SQLAlchemy-1.4.52-cp39-cp39-win32.whl", hash = "sha256:c124912fd4e1bb9d1e7dc193ed482a9f812769cb1e69363ab68e01801e859821"}, - {file = "SQLAlchemy-1.4.52-cp39-cp39-win_amd64.whl", hash = "sha256:2c286fab42e49db23c46ab02479f328b8bdb837d3e281cae546cc4085c83b680"}, - {file = "SQLAlchemy-1.4.52.tar.gz", hash = "sha256:80e63bbdc5217dad3485059bdf6f65a7d43f33c8bde619df5c220edf03d87296"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:4c142852ae192e9fe5aad5c350ea6befe9db14370b34047e1f0f7cf99e63c63b"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:99a1e69d4e26f71e750e9ad6fdc8614fbddb67cfe2173a3628a2566034e223c7"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5ef3fbccb4058355053c51b82fd3501a6e13dd808c8d8cd2561e610c5456013c"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9d6753305936eddc8ed190e006b7bb33a8f50b9854823485eed3a886857ab8d1"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:0f3ca96af060a5250a8ad5a63699180bc780c2edf8abf96c58af175921df847a"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:c4520047006b1d3f0d89e0532978c0688219857eb2fee7c48052560ae76aca1e"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-win32.whl", hash = "sha256:b2a0e3cf0caac2085ff172c3faacd1e00c376e6884b5bc4dd5b6b84623e29e4f"}, + {file = "SQLAlchemy-2.0.29-cp310-cp310-win_amd64.whl", hash = "sha256:01d10638a37460616708062a40c7b55f73e4d35eaa146781c683e0fa7f6c43fb"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:308ef9cb41d099099fffc9d35781638986870b29f744382904bf9c7dadd08513"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:296195df68326a48385e7a96e877bc19aa210e485fa381c5246bc0234c36c78e"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a13b917b4ffe5a0a31b83d051d60477819ddf18276852ea68037a144a506efb9"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4f6d971255d9ddbd3189e2e79d743ff4845c07f0633adfd1de3f63d930dbe673"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:61405ea2d563407d316c63a7b5271ae5d274a2a9fbcd01b0aa5503635699fa1e"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:de7202ffe4d4a8c1e3cde1c03e01c1a3772c92858837e8f3879b497158e4cb44"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-win32.whl", hash = "sha256:b5d7ed79df55a731749ce65ec20d666d82b185fa4898430b17cb90c892741520"}, + {file = "SQLAlchemy-2.0.29-cp311-cp311-win_amd64.whl", hash = "sha256:205f5a2b39d7c380cbc3b5dcc8f2762fb5bcb716838e2d26ccbc54330775b003"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:d96710d834a6fb31e21381c6d7b76ec729bd08c75a25a5184b1089141356171f"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:52de4736404e53c5c6a91ef2698c01e52333988ebdc218f14c833237a0804f1b"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5c7b02525ede2a164c5fa5014915ba3591730f2cc831f5be9ff3b7fd3e30958e"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0dfefdb3e54cd15f5d56fd5ae32f1da2d95d78319c1f6dfb9bcd0eb15d603d5d"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:a88913000da9205b13f6f195f0813b6ffd8a0c0c2bd58d499e00a30eb508870c"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:fecd5089c4be1bcc37c35e9aa678938d2888845a134dd016de457b942cf5a758"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-win32.whl", hash = "sha256:8197d6f7a3d2b468861ebb4c9f998b9df9e358d6e1cf9c2a01061cb9b6cf4e41"}, + {file = "SQLAlchemy-2.0.29-cp312-cp312-win_amd64.whl", hash = "sha256:9b19836ccca0d321e237560e475fd99c3d8655d03da80c845c4da20dda31b6e1"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-macosx_10_9_x86_64.whl", hash = "sha256:87a1d53a5382cdbbf4b7619f107cc862c1b0a4feb29000922db72e5a66a5ffc0"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2a0732dffe32333211801b28339d2a0babc1971bc90a983e3035e7b0d6f06b93"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:90453597a753322d6aa770c5935887ab1fc49cc4c4fdd436901308383d698b4b"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-musllinux_1_1_aarch64.whl", hash = "sha256:ea311d4ee9a8fa67f139c088ae9f905fcf0277d6cd75c310a21a88bf85e130f5"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-musllinux_1_1_x86_64.whl", hash = "sha256:5f20cb0a63a3e0ec4e169aa8890e32b949c8145983afa13a708bc4b0a1f30e03"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-win32.whl", hash = "sha256:e5bbe55e8552019c6463709b39634a5fc55e080d0827e2a3a11e18eb73f5cdbd"}, + {file = "SQLAlchemy-2.0.29-cp37-cp37m-win_amd64.whl", hash = "sha256:c2f9c762a2735600654c654bf48dad388b888f8ce387b095806480e6e4ff6907"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:7e614d7a25a43a9f54fcce4675c12761b248547f3d41b195e8010ca7297c369c"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-macosx_11_0_arm64.whl", hash = "sha256:471fcb39c6adf37f820350c28aac4a7df9d3940c6548b624a642852e727ea586"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:988569c8732f54ad3234cf9c561364221a9e943b78dc7a4aaf35ccc2265f1930"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dddaae9b81c88083e6437de95c41e86823d150f4ee94bf24e158a4526cbead01"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-musllinux_1_1_aarch64.whl", hash = "sha256:334184d1ab8f4c87f9652b048af3f7abea1c809dfe526fb0435348a6fef3d380"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-musllinux_1_1_x86_64.whl", hash = "sha256:38b624e5cf02a69b113c8047cf7f66b5dfe4a2ca07ff8b8716da4f1b3ae81567"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-win32.whl", hash = "sha256:bab41acf151cd68bc2b466deae5deeb9e8ae9c50ad113444151ad965d5bf685b"}, + {file = "SQLAlchemy-2.0.29-cp38-cp38-win_amd64.whl", hash = "sha256:52c8011088305476691b8750c60e03b87910a123cfd9ad48576d6414b6ec2a1d"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:3071ad498896907a5ef756206b9dc750f8e57352113c19272bdfdc429c7bd7de"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:dba622396a3170974f81bad49aacebd243455ec3cc70615aeaef9e9613b5bca5"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7b184e3de58009cc0bf32e20f137f1ec75a32470f5fede06c58f6c355ed42a72"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8c37f1050feb91f3d6c32f864d8e114ff5545a4a7afe56778d76a9aec62638ba"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:bda7ce59b06d0f09afe22c56714c65c957b1068dee3d5e74d743edec7daba552"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:25664e18bef6dc45015b08f99c63952a53a0a61f61f2e48a9e70cec27e55f699"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-win32.whl", hash = "sha256:77d29cb6c34b14af8a484e831ab530c0f7188f8efed1c6a833a2c674bf3c26ec"}, + {file = "SQLAlchemy-2.0.29-cp39-cp39-win_amd64.whl", hash = "sha256:04c487305ab035a9548f573763915189fc0fe0824d9ba28433196f8436f1449c"}, + {file = "SQLAlchemy-2.0.29-py3-none-any.whl", hash = "sha256:dc4ee2d4ee43251905f88637d5281a8d52e916a021384ec10758826f5cbae305"}, + {file = "SQLAlchemy-2.0.29.tar.gz", hash = "sha256:bd9566b8e58cabd700bc367b60e90d9349cd16f0984973f98a9a09f9c64e86f0"}, ] [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 = "!=0.4.17", 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\""} +typing-extensions = ">=4.6.0" [package.extras] aiomysql = ["aiomysql (>=0.2.0)", "greenlet (!=0.4.17)"] +aioodbc = ["aioodbc", "greenlet (!=0.4.17)"] aiosqlite = ["aiosqlite", "greenlet (!=0.4.17)", "typing_extensions (!=3.10.0.1)"] asyncio = ["greenlet (!=0.4.17)"] -asyncmy = ["asyncmy (>=0.2.3,!=0.2.4)", "greenlet (!=0.4.17)"] -mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2)"] +asyncmy = ["asyncmy (>=0.2.3,!=0.2.4,!=0.2.6)", "greenlet (!=0.4.17)"] +mariadb-connector = ["mariadb (>=1.0.1,!=1.1.2,!=1.1.5)"] mssql = ["pyodbc"] mssql-pymssql = ["pymssql"] mssql-pyodbc = ["pyodbc"] -mypy = ["mypy (>=0.910)", "sqlalchemy2-stubs"] -mysql = ["mysqlclient (>=1.4.0)", "mysqlclient (>=1.4.0,<2)"] +mypy = ["mypy (>=0.910)"] +mysql = ["mysqlclient (>=1.4.0)"] mysql-connector = ["mysql-connector-python"] -oracle = ["cx_oracle (>=7)", "cx_oracle (>=7,<8)"] +oracle = ["cx_oracle (>=8)"] +oracle-oracledb = ["oracledb (>=1.0.1)"] postgresql = ["psycopg2 (>=2.7)"] postgresql-asyncpg = ["asyncpg", "greenlet (!=0.4.17)"] -postgresql-pg8000 = ["pg8000 (>=1.16.6,!=1.29.0)"] +postgresql-pg8000 = ["pg8000 (>=1.29.1)"] +postgresql-psycopg = ["psycopg (>=3.0.7)"] postgresql-psycopg2binary = ["psycopg2-binary"] postgresql-psycopg2cffi = ["psycopg2cffi"] -pymysql = ["pymysql", "pymysql (<1)"] +postgresql-psycopgbinary = ["psycopg[binary] (>=3.0.7)"] +pymysql = ["pymysql"] sqlcipher = ["sqlcipher3_binary"] -[[package]] -name = "sqlalchemy2-stubs" -version = "0.0.2a38" -description = "Typing Stubs for SQLAlchemy 1.4" -optional = false -python-versions = ">=3.6" -files = [ - {file = "sqlalchemy2-stubs-0.0.2a38.tar.gz", hash = "sha256:861d722abeb12f13eacd775a9f09379b11a5a9076f469ccd4099961b95800f9e"}, - {file = "sqlalchemy2_stubs-0.0.2a38-py3-none-any.whl", hash = "sha256:b62aa46943807287550e2033dafe07564b33b6a815fbaa3c144e396f9cc53bcb"}, -] - -[package.dependencies] -typing-extensions = ">=3.7.4" - [[package]] name = "sqlmodel" -version = "0.0.10" +version = "0.0.16" description = "SQLModel, SQL databases in Python, designed for simplicity, compatibility, and robustness." optional = false python-versions = ">=3.7,<4.0" files = [ - {file = "sqlmodel-0.0.10-py3-none-any.whl", hash = "sha256:10b3a312f66bed2b88a7b369cd06d1c0e89f62ad8e6303eefa1ea5b3e7b141f4"}, - {file = "sqlmodel-0.0.10.tar.gz", hash = "sha256:632f7f82d67f007161412e7c18279ba0f2b0ecacd5922a65aff89231ebc324ca"}, + {file = "sqlmodel-0.0.16-py3-none-any.whl", hash = "sha256:b972f5d319580d6c37ecc417881f6ec4d1ad3ed3583d0ac0ed43234a28bf605a"}, + {file = "sqlmodel-0.0.16.tar.gz", hash = "sha256:966656f18a8e9a2d159eb215b07fb0cf5222acfae3362707ca611848a8a06bd1"}, ] [package.dependencies] -pydantic = ">=1.9.0,<2.0.0" -SQLAlchemy = ">=1.4.36,<2.0.0" -sqlalchemy2-stubs = "*" +pydantic = ">=1.10.13,<3.0.0" +SQLAlchemy = ">=2.0.0,<2.1.0" [[package]] name = "starlette" @@ -3737,4 +3730,4 @@ testing = ["big-O", "jaraco.functools", "jaraco.itertools", "more-itertools", "p [metadata] lock-version = "2.0" python-versions = "^3.12" -content-hash = "5976a4519c3a3a2290d5df83c1167c765891d81e12c90b723bd405c38a3bf962" +content-hash = "d18072d29d0021e0c07c4954638d5e766b98447afb642b6fa496317a607c5907" diff --git a/apps/api/pyproject.toml b/apps/api/pyproject.toml index dc8748e2..812b699b 100644 --- a/apps/api/pyproject.toml +++ b/apps/api/pyproject.toml @@ -34,7 +34,7 @@ redis = "^5.0.1" requests = "^2.31.0" resend = "^0.8.0" sentry-sdk = {extras = ["fastapi"], version = "^1.39.2"} -sqlmodel = "^0.0.10" +sqlmodel = "^0.0.16" tiktoken = "^0.5.2" uvicorn = "0.29.0" diff --git a/apps/api/src/db/trails.py b/apps/api/src/db/trails.py index 950388d6..da6238c0 100644 --- a/apps/api/src/db/trails.py +++ b/apps/api/src/db/trails.py @@ -20,8 +20,7 @@ class Trail(TrailBase, table=True): class TrailCreate(TrailBase): pass - -# trick because Lists are not supported in SQLModel (runs: list[TrailRun] ) +# TODO: This is a hacky way to get around the list[TrailRun] issue, find a better way to do this class TrailRead(BaseModel): id: Optional[int] = Field(default=None, primary_key=True) trail_uuid: Optional[str] diff --git a/apps/api/src/routers/auth.py b/apps/api/src/routers/auth.py index fd6e87e9..535ebe74 100644 --- a/apps/api/src/routers/auth.py +++ b/apps/api/src/routers/auth.py @@ -65,7 +65,7 @@ async def login( expires=int(timedelta(hours=8).total_seconds()), ) - user = UserRead.from_orm(user) + user = UserRead.model_validate(user) result = { "user": user, diff --git a/apps/api/src/routers/dev.py b/apps/api/src/routers/dev.py index e5d11d23..79698abe 100644 --- a/apps/api/src/routers/dev.py +++ b/apps/api/src/routers/dev.py @@ -8,7 +8,7 @@ router = APIRouter() @router.get("/config") async def config(): config = get_learnhouse_config() - return config.dict() + return config.model_dump() diff --git a/apps/api/src/routers/users.py b/apps/api/src/routers/users.py index e226f6b6..5dc621f3 100644 --- a/apps/api/src/routers/users.py +++ b/apps/api/src/routers/users.py @@ -42,7 +42,7 @@ async def api_get_current_user(current_user: User = Depends(get_current_user)): """ Get current user """ - return current_user.dict() + return current_user.model_dump() @router.get("/session") diff --git a/apps/api/src/security/auth.py b/apps/api/src/security/auth.py index f90bf9d6..dc9c6fd7 100644 --- a/apps/api/src/security/auth.py +++ b/apps/api/src/security/auth.py @@ -96,7 +96,7 @@ async def get_current_user( user = await security_get_user(request, db_session, email=token_data.username) # type: ignore # treated as an email if user is None: raise credentials_exception - return PublicUser(**user.dict()) + return PublicUser(**user.model_dump()) else: return AnonymousUser() diff --git a/apps/api/src/security/rbac/rbac.py b/apps/api/src/security/rbac/rbac.py index 4ce18736..2e92ff09 100644 --- a/apps/api/src/security/rbac/rbac.py +++ b/apps/api/src/security/rbac/rbac.py @@ -103,7 +103,7 @@ async def authorization_verify_based_on_roles( # Find in roles list if there is a role that matches users action for this type of element for role in user_roles_in_organization_and_standard_roles: - role = Role.from_orm(role) + role = Role.model_validate(role) if role.rights: rights = role.rights if rights[element_type][f"action_{action}"] is True: @@ -135,7 +135,7 @@ async def authorization_verify_based_on_org_admin_status( # Find in roles list if there is a role that matches users action for this type of element for role in user_roles_in_organization_and_standard_roles: - role = Role.from_orm(role) + role = Role.model_validate(role) if role.id == 1 or role.id == 2: return True else: diff --git a/apps/api/src/services/ai/ai.py b/apps/api/src/services/ai/ai.py index 5b8cc7b7..8afc7f51 100644 --- a/apps/api/src/services/ai/ai.py +++ b/apps/api/src/services/ai/ai.py @@ -37,7 +37,7 @@ def ai_start_activity_chat_session( ) activity = db_session.exec(statement).first() - activity = ActivityRead.from_orm(activity) + activity = ActivityRead.model_validate(activity) # Get the Course statement = ( @@ -46,7 +46,7 @@ def ai_start_activity_chat_session( .where(Activity.activity_uuid == chat_session_object.activity_uuid) ) course = db_session.exec(statement).first() - course = CourseRead.from_orm(course) + course = CourseRead.model_validate(course) # Get the Organization statement = select(Organization).where(Organization.id == course.org_id) @@ -85,7 +85,7 @@ def ai_start_activity_chat_session( result = db_session.exec(statement) org_config = result.first() - org_config = OrganizationConfig.from_orm(org_config) + org_config = OrganizationConfig.model_validate(org_config) embeddings = org_config.config["AIConfig"]["embeddings"] ai_model = org_config.config["AIConfig"]["ai_model"] @@ -131,7 +131,7 @@ def ai_send_activity_chat_message( ) activity = db_session.exec(statement).first() - activity = ActivityRead.from_orm(activity) + activity = ActivityRead.model_validate(activity) # Get the Course statement = ( @@ -140,7 +140,7 @@ def ai_send_activity_chat_message( .where(Activity.activity_uuid == chat_session_object.activity_uuid) ) course = db_session.exec(statement).first() - course = CourseRead.from_orm(course) + course = CourseRead.model_validate(course) # Get the Organization statement = select(Organization).where(Organization.id == course.org_id) @@ -176,7 +176,7 @@ def ai_send_activity_chat_message( result = db_session.exec(statement) org_config = result.first() - org_config = OrganizationConfig.from_orm(org_config) + org_config = OrganizationConfig.model_validate(org_config) embeddings = org_config.config["AIConfig"]["embeddings"] ai_model = org_config.config["AIConfig"]["ai_model"] diff --git a/apps/api/src/services/blocks/block_types/imageBlock/imageBlock.py b/apps/api/src/services/blocks/block_types/imageBlock/imageBlock.py index 8e5ce688..34ceab64 100644 --- a/apps/api/src/services/blocks/block_types/imageBlock/imageBlock.py +++ b/apps/api/src/services/blocks/block_types/imageBlock/imageBlock.py @@ -54,7 +54,7 @@ async def create_image_block( block = Block( activity_id=activity.id if activity.id else 0, block_type=BlockTypeEnum.BLOCK_IMAGE, - content=block_data.dict(), + content=block_data.model_dump(), org_id=org.id if org.id else 0, course_id=course.id if course.id else 0, block_uuid=block_uuid, @@ -67,7 +67,7 @@ async def create_image_block( db_session.commit() db_session.refresh(block) - block = BlockRead.from_orm(block) + block = BlockRead.model_validate(block) return block @@ -80,7 +80,7 @@ async def get_image_block( if block: - block = BlockRead.from_orm(block) + block = BlockRead.model_validate(block) return block else: diff --git a/apps/api/src/services/blocks/block_types/pdfBlock/pdfBlock.py b/apps/api/src/services/blocks/block_types/pdfBlock/pdfBlock.py index 48c06a20..1d60a33b 100644 --- a/apps/api/src/services/blocks/block_types/pdfBlock/pdfBlock.py +++ b/apps/api/src/services/blocks/block_types/pdfBlock/pdfBlock.py @@ -55,7 +55,7 @@ async def create_pdf_block( block = Block( activity_id=activity.id if activity.id else 0, block_type=BlockTypeEnum.BLOCK_DOCUMENT_PDF, - content=block_data.dict(), + content=block_data.model_dump(), org_id=org.id if org.id else 0, course_id=course.id if course.id else 0, block_uuid=block_uuid, @@ -68,7 +68,7 @@ async def create_pdf_block( db_session.commit() db_session.refresh(block) - block = BlockRead.from_orm(block) + block = BlockRead.model_validate(block) return block @@ -84,6 +84,6 @@ async def get_pdf_block( status_code=status.HTTP_404_NOT_FOUND, detail="Video file does not exist" ) - block = BlockRead.from_orm(block) + block = BlockRead.model_validate(block) return block diff --git a/apps/api/src/services/blocks/block_types/videoBlock/videoBlock.py b/apps/api/src/services/blocks/block_types/videoBlock/videoBlock.py index ab6735d7..da3d91f8 100644 --- a/apps/api/src/services/blocks/block_types/videoBlock/videoBlock.py +++ b/apps/api/src/services/blocks/block_types/videoBlock/videoBlock.py @@ -55,7 +55,7 @@ async def create_video_block( block = Block( activity_id=activity.id if activity.id else 0, block_type=BlockTypeEnum.BLOCK_VIDEO, - content=block_data.dict(), + content=block_data.model_dump(), org_id=org.id if org.id else 0, course_id=course.id if course.id else 0, block_uuid=block_uuid, @@ -68,7 +68,7 @@ async def create_video_block( db_session.commit() db_session.refresh(block) - block = BlockRead.from_orm(block) + block = BlockRead.model_validate(block) return block @@ -84,6 +84,6 @@ async def get_video_block( status_code=status.HTTP_404_NOT_FOUND, detail="Video file does not exist" ) - block = BlockRead.from_orm(block) + block = BlockRead.model_validate(block) return block diff --git a/apps/api/src/services/courses/activities/activities.py b/apps/api/src/services/courses/activities/activities.py index 3b970818..e976f8c3 100644 --- a/apps/api/src/services/courses/activities/activities.py +++ b/apps/api/src/services/courses/activities/activities.py @@ -41,7 +41,7 @@ async def create_activity( await rbac_check(request, chapter.chapter_uuid, current_user, "create", db_session) # Create Activity - activity = Activity(**activity_object.dict()) + activity = Activity(**activity_object.model_dump()) activity.activity_uuid = str(f"activity_{uuid4()}") activity.creation_date = str(datetime.now()) @@ -81,7 +81,7 @@ async def create_activity( db_session.commit() db_session.refresh(activity_chapter) - return ActivityRead.from_orm(activity) + return ActivityRead.model_validate(activity) async def get_activity( @@ -112,7 +112,7 @@ async def get_activity( # RBAC check await rbac_check(request, course.course_uuid, current_user, "read", db_session) - activity = ActivityRead.from_orm(activity) + activity = ActivityRead.model_validate(activity) return activity @@ -147,7 +147,7 @@ async def update_activity( db_session.commit() db_session.refresh(activity) - activity = ActivityRead.from_orm(activity) + activity = ActivityRead.model_validate(activity) return activity @@ -216,7 +216,7 @@ async def get_activities( # RBAC check await rbac_check(request, "activity_x", current_user, "read", db_session) - activities = [ActivityRead.from_orm(activity) for activity in activities] + activities = [ActivityRead.model_validate(activity) for activity in activities] return activities diff --git a/apps/api/src/services/courses/activities/pdf.py b/apps/api/src/services/courses/activities/pdf.py index 0fbbe5aa..bb97da54 100644 --- a/apps/api/src/services/courses/activities/pdf.py +++ b/apps/api/src/services/courses/activities/pdf.py @@ -135,7 +135,7 @@ async def create_documentpdf_activity( db_session.commit() db_session.refresh(activity_chapter) - return ActivityRead.from_orm(activity) + return ActivityRead.model_validate(activity) ## 🔒 RBAC Utils ## diff --git a/apps/api/src/services/courses/activities/video.py b/apps/api/src/services/courses/activities/video.py index 5070814c..629a76c7 100644 --- a/apps/api/src/services/courses/activities/video.py +++ b/apps/api/src/services/courses/activities/video.py @@ -105,7 +105,7 @@ async def create_video_activity( ) # create activity - activity = Activity.from_orm(activity_object) + activity = Activity.model_validate(activity_object) db_session.add(activity) db_session.commit() db_session.refresh(activity) @@ -136,7 +136,7 @@ async def create_video_activity( db_session.commit() db_session.refresh(chapter_activity_object) - return ActivityRead.from_orm(activity) + return ActivityRead.model_validate(activity) class ExternalVideo(BaseModel): @@ -200,7 +200,7 @@ async def create_external_video_activity( ) # create activity - activity = Activity.from_orm(activity_object) + activity = Activity.model_validate(activity_object) db_session.add(activity) db_session.commit() db_session.refresh(activity) @@ -220,7 +220,7 @@ async def create_external_video_activity( db_session.add(chapter_activity_object) db_session.commit() - return ActivityRead.from_orm(activity) + return ActivityRead.model_validate(activity) async def rbac_check( diff --git a/apps/api/src/services/courses/chapters.py b/apps/api/src/services/courses/chapters.py index 31b3d7ef..ee8ce1b5 100644 --- a/apps/api/src/services/courses/chapters.py +++ b/apps/api/src/services/courses/chapters.py @@ -34,7 +34,7 @@ async def create_chapter( current_user: PublicUser | AnonymousUser, db_session: Session, ) -> ChapterRead: - chapter = Chapter.from_orm(chapter_object) + chapter = Chapter.model_validate(chapter_object) # Get COurse statement = select(Course).where(Course.id == chapter_object.course_id) @@ -68,7 +68,7 @@ async def create_chapter( db_session.commit() db_session.refresh(chapter) - chapter = ChapterRead(**chapter.dict(), activities=[]) + chapter = ChapterRead(**chapter.model_dump(), activities=[]) # Check if COurseChapter link exists @@ -135,8 +135,8 @@ async def get_chapter( activities = db_session.exec(statement).all() chapter = ChapterRead( - **chapter.dict(), - activities=[ActivityRead(**activity.dict()) for activity in activities], + **chapter.model_dump(), + activities=[ActivityRead(**activity.model_dump()) for activity in activities], ) return chapter @@ -231,7 +231,7 @@ async def get_course_chapters( ) chapters = db_session.exec(statement).all() - chapters = [ChapterRead(**chapter.dict(), activities=[]) for chapter in chapters] + chapters = [ChapterRead(**chapter.model_dump(), activities=[]) for chapter in chapters] # RBAC check await rbac_check(request, course.course_uuid, current_user, "read", db_session) # type: ignore @@ -255,7 +255,7 @@ async def get_course_chapters( activity = db_session.exec(statement).first() if activity: - chapter.activities.append(ActivityRead(**activity.dict())) + chapter.activities.append(ActivityRead(**activity.model_dump())) return chapters diff --git a/apps/api/src/services/courses/collections.py b/apps/api/src/services/courses/collections.py index 51999804..83f976a7 100644 --- a/apps/api/src/services/courses/collections.py +++ b/apps/api/src/services/courses/collections.py @@ -64,7 +64,7 @@ async def get_collection( courses = db_session.exec(statement).all() - collection = CollectionRead(**collection.dict(), courses=courses) + collection = CollectionRead(**collection.model_dump(), courses=courses) return collection @@ -75,7 +75,7 @@ async def create_collection( current_user: PublicUser, db_session: Session, ) -> CollectionRead: - collection = Collection.from_orm(collection_object) + collection = Collection.model_validate(collection_object) # RBAC check await rbac_check(request, "collection_x", current_user, "create", db_session) @@ -115,9 +115,9 @@ async def create_collection( ) courses = db_session.exec(statement).all() - collection = CollectionRead(**collection.dict(), courses=courses) + collection = CollectionRead(**collection.model_dump(), courses=courses) - return CollectionRead.from_orm(collection) + return CollectionRead.model_validate(collection) async def update_collection( @@ -189,7 +189,7 @@ async def update_collection( courses = db_session.exec(statement).all() - collection = CollectionRead(**collection.dict(), courses=courses) + collection = CollectionRead(**collection.model_dump(), courses=courses) return collection @@ -270,7 +270,7 @@ async def get_collections( courses = db_session.exec(statement).all() - collection = CollectionRead(**collection.dict(), courses=courses) + collection = CollectionRead(**collection.model_dump(), courses=courses) collections_with_courses.append(collection) return collections_with_courses diff --git a/apps/api/src/services/courses/courses.py b/apps/api/src/services/courses/courses.py index 3e2458ea..1721c01d 100644 --- a/apps/api/src/services/courses/courses.py +++ b/apps/api/src/services/courses/courses.py @@ -5,7 +5,6 @@ from sqlmodel import Session, select from src.db.usergroup_resources import UserGroupResource from src.db.usergroup_user import UserGroupUser from src.db.organizations import Organization -from src.db.trails import TrailRead from src.services.trail.trail import get_user_trail_with_orgid from src.db.resource_authors import ResourceAuthor, ResourceAuthorshipEnum from src.db.users import PublicUser, AnonymousUser, User, UserRead @@ -53,9 +52,9 @@ async def get_course( authors = db_session.exec(authors_statement).all() # convert from User to UserRead - authors = [UserRead.from_orm(author) for author in authors] + authors = [UserRead.model_validate(author) for author in authors] - course = CourseRead(**course.dict(), authors=authors) + course = CourseRead(**course.model_dump(), authors=authors) return course @@ -90,9 +89,9 @@ async def get_course_meta( authors = db_session.exec(authors_statement).all() # convert from User to UserRead - authors = [UserRead.from_orm(author) for author in authors] + authors = [UserRead.model_validate(author) for author in authors] - course = CourseRead(**course.dict(), authors=authors) + course = CourseRead(**course.model_dump(), authors=authors) # Get course chapters chapters = await get_course_chapters(request, course.id, db_session, current_user) @@ -106,10 +105,9 @@ async def get_course_meta( trail = await get_user_trail_with_orgid( request, current_user, course.org_id, db_session ) - trail = TrailRead.from_orm(trail) return FullCourseReadWithTrail( - **course.dict(), + **course.model_dump(), chapters=chapters, trail=trail if trail else None, ) @@ -123,7 +121,7 @@ async def create_course( db_session: Session, thumbnail_file: UploadFile | None = None, ): - course = Course.from_orm(course_object) + course = Course.model_validate(course_object) # RBAC check await rbac_check(request, "course_x", current_user, "create", db_session) @@ -178,11 +176,11 @@ async def create_course( authors = db_session.exec(authors_statement).all() # convert from User to UserRead - authors = [UserRead.from_orm(author) for author in authors] + authors = [UserRead.model_validate(author) for author in authors] - course = CourseRead(**course.dict(), authors=authors) + course = CourseRead(**course.model_dump(), authors=authors) - return CourseRead.from_orm(course) + return CourseRead.model_validate(course) async def update_course_thumbnail( @@ -242,9 +240,9 @@ async def update_course_thumbnail( authors = db_session.exec(authors_statement).all() # convert from User to UserRead - authors = [UserRead.from_orm(author) for author in authors] + authors = [UserRead.model_validate(author) for author in authors] - course = CourseRead(**course.dict(), authors=authors) + course = CourseRead(**course.model_dump(), authors=authors) return course @@ -289,9 +287,9 @@ async def update_course( authors = db_session.exec(authors_statement).all() # convert from User to UserRead - authors = [UserRead.from_orm(author) for author in authors] + authors = [UserRead.model_validate(author) for author in authors] - course = CourseRead(**course.dict(), authors=authors) + course = CourseRead(**course.model_dump(), authors=authors) return course @@ -351,9 +349,7 @@ async def get_courses_orgslug( statement_usergroup = ( select(Course) .join(Organization) - .join( - UserGroupResource, UserGroupResource.resource_uuid == Course.course_uuid - ) + .join(UserGroupResource, UserGroupResource.resource_uuid == Course.course_uuid) .join( UserGroupUser, UserGroupUser.usergroup_id == UserGroupResource.usergroup_id ) @@ -365,10 +361,12 @@ async def get_courses_orgslug( statement_public, statement_author, statement_usergroup ).subquery() - courses = db_session.execute(select([statement_complete])).all() + # TODO: migrate this to exec + courses = db_session.execute(select(statement_complete)).all() # TODO: I have no idea why this is necessary, but it is - courses = [CourseRead(**dict(course._mapping), authors=[]) for course in courses] + courses = [CourseRead(**course._asdict(), authors=[]) for course in courses] + # for every course, get the authors for course in courses: @@ -380,7 +378,7 @@ async def get_courses_orgslug( authors = db_session.exec(authors_statement).all() # convert from User to UserRead - authors = [UserRead.from_orm(author) for author in authors] + authors = [UserRead.model_validate(author) for author in authors] course.authors = authors diff --git a/apps/api/src/services/install/install.py b/apps/api/src/services/install/install.py index 5c17cc88..cd200e4e 100644 --- a/apps/api/src/services/install/install.py +++ b/apps/api/src/services/install/install.py @@ -25,7 +25,7 @@ async def isInstallModeEnabled(): async def create_install_instance(request: Request, data: dict, db_session: Session): - install = Install.from_orm(data) + install = Install.model_validate(data) # complete install instance install.install_uuid = str(f"install_{uuid4()}") @@ -41,7 +41,7 @@ async def create_install_instance(request: Request, data: dict, db_session: Sess # refresh install instance db_session.refresh(install) - install = InstallRead.from_orm(install) + install = InstallRead.model_validate(install) return install @@ -56,7 +56,7 @@ async def get_latest_install_instance(request: Request, db_session: Session): detail="No install instance found", ) - install = InstallRead.from_orm(install) + install = InstallRead.model_validate(install) return install @@ -82,7 +82,7 @@ async def update_install_instance( # refresh install instance db_session.refresh(install) - install = InstallRead.from_orm(install) + install = InstallRead.model_validate(install) return install @@ -279,9 +279,9 @@ async def install_default_elements(db_session: Session): ) # Serialize rights to JSON - role_global_admin.rights = role_global_admin.rights.dict() # type: ignore - role_global_maintainer.rights = role_global_maintainer.rights.dict() # type: ignore - role_global_user.rights = role_global_user.rights.dict() # type: ignore + role_global_admin.rights = role_global_admin.rights.model_dump() # type: ignore + role_global_maintainer.rights = role_global_maintainer.rights.model_dump() # type: ignore + role_global_user.rights = role_global_user.rights.model_dump() # type: ignore # Insert roles in DB db_session.add(role_global_admin) @@ -301,7 +301,7 @@ async def install_default_elements(db_session: Session): async def install_create_organization( org_object: OrganizationCreate, db_session: Session ): - org = Organization.from_orm(org_object) + org = Organization.model_validate(org_object) # Complete the org object org.org_uuid = f"org_{uuid4()}" @@ -318,7 +318,7 @@ async def install_create_organization( async def install_create_organization_user( user_object: UserCreate, org_slug: str, db_session: Session ): - user = User.from_orm(user_object) + user = User.model_validate(user_object) # Complete the user object user.user_uuid = f"user_{uuid4()}" @@ -390,6 +390,6 @@ async def install_create_organization_user( db_session.commit() db_session.refresh(user_organization) - user = UserRead.from_orm(user) + user = UserRead.model_validate(user) return user diff --git a/apps/api/src/services/orgs/orgs.py b/apps/api/src/services/orgs/orgs.py index 262adb93..9cda7a2c 100644 --- a/apps/api/src/services/orgs/orgs.py +++ b/apps/api/src/services/orgs/orgs.py @@ -59,9 +59,9 @@ async def get_organization( if org_config is None: logging.error(f"Organization {org_id} has no config") - config = OrganizationConfig.from_orm(org_config) if org_config else {} + config = OrganizationConfig.model_validate(org_config) if org_config else {} - org = OrganizationRead(**org.dict(), config=config) + org = OrganizationRead(**org.model_dump(), config=config) return org @@ -95,9 +95,9 @@ async def get_organization_by_slug( if org_config is None: logging.error(f"Organization {org_slug} has no config") - config = OrganizationConfig.from_orm(org_config) if org_config else {} + config = OrganizationConfig.model_validate(org_config) if org_config else {} - org = OrganizationRead(**org.dict(), config=config) + org = OrganizationRead(**org.model_dump(), config=config) return org @@ -119,7 +119,7 @@ async def create_org( detail="Organization already exists", ) - org = Organization.from_orm(org_object) + org = Organization.model_validate(org_object) if isinstance(current_user, AnonymousUser): raise HTTPException( @@ -203,9 +203,9 @@ async def create_org( if org_config is None: logging.error(f"Organization {org.id} has no config") - config = OrganizationConfig.from_orm(org_config) + config = OrganizationConfig.model_validate(org_config) - org = OrganizationRead(**org.dict(), config=config) + org = OrganizationRead(**org.model_dump(), config=config) return org @@ -229,7 +229,7 @@ async def create_org_with_config( detail="Organization already exists", ) - org = Organization.from_orm(org_object) + org = Organization.model_validate(org_object) if isinstance(current_user, AnonymousUser): raise HTTPException( @@ -284,9 +284,9 @@ async def create_org_with_config( if org_config is None: logging.error(f"Organization {org.id} has no config") - config = OrganizationConfig.from_orm(org_config) + config = OrganizationConfig.model_validate(org_config) - org = OrganizationRead(**org.dict(), config=config) + org = OrganizationRead(**org.model_dump(), config=config) return org @@ -336,7 +336,7 @@ async def update_org( db_session.commit() db_session.refresh(org) - org = OrganizationRead.from_orm(org) + org = OrganizationRead.model_validate(org) return org diff --git a/apps/api/src/services/orgs/users.py b/apps/api/src/services/orgs/users.py index 207508a8..8cb0c4d6 100644 --- a/apps/api/src/services/orgs/users.py +++ b/apps/api/src/services/orgs/users.py @@ -84,8 +84,8 @@ async def get_organization_users( # skip this user continue - user = UserRead.from_orm(user) - role = RoleRead.from_orm(role) + user = UserRead.model_validate(user) + role = RoleRead.model_validate(role) org_user = OrganizationUser( user=user, @@ -293,8 +293,8 @@ async def invite_batch_users( # skip this user continue - org = OrganizationRead.from_orm(org) - user = UserRead.from_orm(user) + org = OrganizationRead.model_validate(org) + user = UserRead.model_validate(user) isEmailSent = send_invite_email( org, diff --git a/apps/api/src/services/roles/roles.py b/apps/api/src/services/roles/roles.py index 84c03b00..c5939c2c 100644 --- a/apps/api/src/services/roles/roles.py +++ b/apps/api/src/services/roles/roles.py @@ -17,7 +17,7 @@ async def create_role( role_object: RoleCreate, current_user: PublicUser, ): - role = Role.from_orm(role_object) + role = Role.model_validate(role_object) # RBAC check await rbac_check(request, current_user, "create", "role_xxx", db_session) @@ -31,7 +31,7 @@ async def create_role( db_session.commit() db_session.refresh(role) - role = RoleRead(**role.dict()) + role = RoleRead(**role.model_dump()) return role @@ -53,7 +53,7 @@ async def read_role( # RBAC check await rbac_check(request, current_user, "read", role.role_uuid, db_session) - role = RoleRead(**role.dict()) + role = RoleRead(**role.model_dump()) return role @@ -93,7 +93,7 @@ async def update_role( db_session.commit() db_session.refresh(role) - role = RoleRead(**role.dict()) + role = RoleRead(**role.model_dump()) return role diff --git a/apps/api/src/services/trail/trail.py b/apps/api/src/services/trail/trail.py index e3485b9d..6dd5c15b 100644 --- a/apps/api/src/services/trail/trail.py +++ b/apps/api/src/services/trail/trail.py @@ -28,7 +28,7 @@ async def create_user_trail( detail="Trail already exists", ) - trail = Trail.from_orm(trail_object) + trail = Trail.model_validate(trail_object) trail.creation_date = str(datetime.now()) trail.update_date = str(datetime.now()) @@ -91,7 +91,7 @@ async def get_user_trails( trail_step.data = dict(course=course) trail_read = TrailRead( - **trail.dict(), + **trail.model_dump(), runs=trail_runs, ) @@ -176,7 +176,7 @@ async def get_user_trail_with_orgid( trail_step.data = dict(course=course) trail_read = TrailRead( - **trail.dict(), + **trail.model_dump(), runs=trail_runs, ) @@ -276,7 +276,7 @@ async def add_activity_to_trail( trail_step.data = dict(course=course) trail_read = TrailRead( - **trail.dict(), + **trail.model_dump(), runs=trail_runs, ) @@ -357,7 +357,7 @@ async def add_course_to_trail( trail_step.data = dict(course=course) trail_read = TrailRead( - **trail.dict(), + **trail.model_dump(), runs=trail_runs, ) @@ -426,7 +426,7 @@ async def remove_course_from_trail( trail_step.data = dict(course=course) trail_read = TrailRead( - **trail.dict(), + **trail.model_dump(), runs=trail_runs, ) diff --git a/apps/api/src/services/users/password_reset.py b/apps/api/src/services/users/password_reset.py index 16b15e5a..092d50cc 100644 --- a/apps/api/src/services/users/password_reset.py +++ b/apps/api/src/services/users/password_reset.py @@ -93,9 +93,9 @@ async def send_reset_password_code( ex=ttl, ) - user = UserRead.from_orm(user) + user = UserRead.model_validate(user) - org = OrganizationRead.from_orm(org) + org = OrganizationRead.model_validate(org) # Send reset code via email isEmailSent = send_password_reset_email( diff --git a/apps/api/src/services/users/usergroups.py b/apps/api/src/services/users/usergroups.py index 1ad62e4b..84b5de96 100644 --- a/apps/api/src/services/users/usergroups.py +++ b/apps/api/src/services/users/usergroups.py @@ -22,7 +22,7 @@ async def create_usergroup( usergroup_create: UserGroupCreate, ) -> UserGroupRead: - usergroup = UserGroup.from_orm(usergroup_create) + usergroup = UserGroup.model_validate(usergroup_create) # RBAC check await rbac_check( @@ -53,7 +53,7 @@ async def create_usergroup( db_session.commit() db_session.refresh(usergroup) - usergroup = UserGroupRead.from_orm(usergroup) + usergroup = UserGroupRead.model_validate(usergroup) return usergroup @@ -83,7 +83,7 @@ async def read_usergroup_by_id( db_session=db_session, ) - usergroup = UserGroupRead.from_orm(usergroup) + usergroup = UserGroupRead.model_validate(usergroup) return usergroup @@ -125,7 +125,7 @@ async def get_users_linked_to_usergroup( user = db_session.exec(statement).first() users.append(user) - users = [UserRead.from_orm(user) for user in users] + users = [UserRead.model_validate(user) for user in users] return users @@ -149,7 +149,7 @@ async def read_usergroups_by_org_id( db_session=db_session, ) - usergroups = [UserGroupRead.from_orm(usergroup) for usergroup in usergroups] + usergroups = [UserGroupRead.model_validate(usergroup) for usergroup in usergroups] return usergroups @@ -184,7 +184,7 @@ async def get_usergroups_by_resource( usergroup = db_session.exec(statement).first() usergroups.append(usergroup) - usergroups = [UserGroupRead.from_orm(usergroup) for usergroup in usergroups] + usergroups = [UserGroupRead.model_validate(usergroup) for usergroup in usergroups] return usergroups @@ -223,7 +223,7 @@ async def update_usergroup_by_id( db_session.commit() db_session.refresh(usergroup) - usergroup = UserGroupRead.from_orm(usergroup) + usergroup = UserGroupRead.model_validate(usergroup) return usergroup diff --git a/apps/api/src/services/users/users.py b/apps/api/src/services/users/users.py index 70d6ddc4..f96c94b6 100644 --- a/apps/api/src/services/users/users.py +++ b/apps/api/src/services/users/users.py @@ -37,7 +37,7 @@ async def create_user( user_object: UserCreate, org_id: int, ): - user = User.from_orm(user_object) + user = User.model_validate(user_object) # RBAC check await rbac_check(request, current_user, "create", "user_x", db_session) @@ -104,7 +104,7 @@ async def create_user( db_session.commit() db_session.refresh(user_organization) - user = UserRead.from_orm(user) + user = UserRead.model_validate(user) # Send Account creation email send_account_creation_email( @@ -157,7 +157,7 @@ async def create_user_without_org( current_user: PublicUser | AnonymousUser, user_object: UserCreate, ): - user = User.from_orm(user_object) + user = User.model_validate(user_object) # RBAC check await rbac_check(request, current_user, "create", "user_x", db_session) @@ -201,7 +201,7 @@ async def create_user_without_org( db_session.commit() db_session.refresh(user) - user = UserRead.from_orm(user) + user = UserRead.model_validate(user) # Send Account creation email send_account_creation_email( @@ -270,7 +270,7 @@ async def update_user( db_session.commit() db_session.refresh(user) - user = UserRead.from_orm(user) + user = UserRead.model_validate(user) return user @@ -315,7 +315,7 @@ async def update_user_avatar( db_session.commit() db_session.refresh(user) - user = UserRead.from_orm(user) + user = UserRead.model_validate(user) return user @@ -354,7 +354,7 @@ async def update_user_password( db_session.commit() db_session.refresh(user) - user = UserRead.from_orm(user) + user = UserRead.model_validate(user) return user @@ -378,7 +378,7 @@ async def read_user_by_id( # RBAC check await rbac_check(request, current_user, "read", user.user_uuid, db_session) - user = UserRead.from_orm(user) + user = UserRead.model_validate(user) return user @@ -402,7 +402,7 @@ async def read_user_by_uuid( # RBAC check await rbac_check(request, current_user, "read", user.user_uuid, db_session) - user = UserRead.from_orm(user) + user = UserRead.model_validate(user) return user @@ -422,7 +422,7 @@ async def get_user_session( detail="User does not exist", ) - user = UserRead.from_orm(user) + user = UserRead.model_validate(user) # Get roles and orgs statement = ( @@ -445,8 +445,8 @@ async def get_user_session( roles.append( UserRoleWithOrg( - role=RoleRead.from_orm(role), - org=OrganizationRead.from_orm(org), + role=RoleRead.model_validate(role), + org=OrganizationRead.model_validate(org), ) ) @@ -531,7 +531,7 @@ async def security_get_user(request: Request, db_session: Session, email: str) - detail="User with Email does not exist", ) - user = User(**user.dict()) + user = User(**user.model_dump()) return user