diff --git a/.github/workflows/code_quality.yaml b/.github/workflows/code_quality.yaml index 4fb33dcf0ad..7ac55ad1033 100644 --- a/.github/workflows/code_quality.yaml +++ b/.github/workflows/code_quality.yaml @@ -13,7 +13,7 @@ jobs: - uses: actions/checkout@v4 - uses: actions/setup-python@v3 with: - python-version: "3.11" + python-version: "3.13" - name: Install git-secrets in the repository run: git secrets --install - name: Install git-secrets aws register in the repository diff --git a/Pipfile b/Pipfile index 1cc5247875a..070b1245963 100644 --- a/Pipfile +++ b/Pipfile @@ -11,13 +11,13 @@ alembic = "==1.14.0" asyncpg = "==0.30.0" azure-storage-blob = "==12.24.0" bcrypt = "==4.2.1" -boto3 = "==1.35.*" +boto3 = "==1.36.*" fastapi = "==0.115.6" fastapi-mail = "==1.2.9" firebase-admin = "==6.6.*" httpx = "==0.28.*" jinja2 = "==3.1.*" -more-itertools = "==10.5.0" +more-itertools = "==10.6.0" nh3 = "==0.2.20" opentelemetry-api = "==1.27.0" opentelemetry-distro = "==0.48b0" @@ -53,9 +53,9 @@ taskiq-fastapi = "==0.3.*" taskiq-redis = "==1.0.2" typer = "==0.15.*" uvicorn = { extras = ["standard"], version = "==0.34.*" } -ddtrace = "==2.*" +ddtrace = "==2.19.*" bytecode = "==0.16.0" -structlog = "==24.4.0" +structlog = "==25.1.*" asgi-correlation-id = "==4.3.4" @@ -78,7 +78,7 @@ pytest-env = "==1.1.5" pytest-lazy-fixtures = "==1.*" pytest-mock = "==3.14.0" reproschema = "==0.6.2" -ruff = "==0.8.*" +ruff = "==0.9.*" types-aiofiles = "==24.1.0.*" types-cachetools = "==5.5.0.*" types-python-dateutil = "==2.9.0.*" @@ -87,7 +87,7 @@ types-requests = "==2.32.0.*" typing-extensions = "==4.12.2" [requires] -python_version = "3.11" +python_version = "3.13" [scripts] cli = "python src/cli.py" diff --git a/Pipfile.lock b/Pipfile.lock index 570b9d20843..549cfa75034 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,11 +1,11 @@ { "_meta": { "hash": { - "sha256": "9d1d00c546c92aae6b7c89cacf2ad8f68cc4cab636f307bbddb252dd82883f70" + "sha256": "db0df4fa7da0f62d7554414d83b983b3c93b2005d38e68cd6a4efa12a87aa0e5" }, "pipfile-spec": 6, "requires": { - "python_version": "3.11" + "python_version": "3.13" }, "sources": [ { @@ -160,11 +160,11 @@ }, "anyio": { "hashes": [ - "sha256:2f834749c602966b7d456a7567cafcb309f96482b5081d14ac93ccd457f9dd48", - "sha256:ea60c3723ab42ba6fff7e8ccb0488c898ec538ff4df1f1d5e642c3601d07e352" + "sha256:1d9fe889df5212298c0c0723fa20479d1b94883a2df44bd3897aa91083316f7a", + "sha256:b5011f270ab5eb0abf13385f851315585cc37ef330dd88e27ec3d34d651fd47a" ], "markers": "python_version >= '3.9'", - "version": "==4.7.0" + "version": "==4.8.0" }, "asgi-correlation-id": { "hashes": [ @@ -306,20 +306,20 @@ }, "boto3": { "hashes": [ - "sha256:b0874233057995a8f0c813f5b45a36c09630e74c43d7a7c64db2feef2915d493", - "sha256:dc56caaaab2157a4bfc109c88b50cd032f3ac66c06d17f8ee335b798eaf53e5c" + "sha256:258ab77225a81d3cf3029c9afe9920cd9dec317689dfadec6f6f0a23130bb60a", + "sha256:eb21380d73fec6645439c0d802210f72a0cdb3295b02953f246ff53f512faa8f" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==1.35.90" + "version": "==1.36.1" }, "botocore": { "hashes": [ - "sha256:51dcbe1b32e2ac43dac17091f401a00ce5939f76afe999081802009cce1e92e4", - "sha256:f007f58e8e3c1ad0412a6ddfae40ed92a7bca571c068cb959902bcf107f2ae48" + "sha256:dec513b4eb8a847d79bbefdcdd07040ed9d44c20b0001136f0890a03d595705a", + "sha256:f789a6f272b5b3d8f8756495019785e33868e5e00dd9662a3ee7959ac939bb12" ], "markers": "python_version >= '3.8'", - "version": "==1.35.90" + "version": "==1.36.1" }, "bytecode": { "hashes": [ @@ -332,11 +332,11 @@ }, "cachecontrol": { "hashes": [ - "sha256:06ef916a1e4eb7dba9948cdfc9c76e749db2e02104a9a1277e8b642591a0f717", - "sha256:65e3abd62b06382ce3894df60dde9e0deb92aeb734724f68fa4f3b91e97206b9" + "sha256:7d47d19f866409b98ff6025b6a0fca8e4c791fb31abbd95f622093894ce903a2", + "sha256:ebad2091bf12d0d200dfc2464330db638c5deb41d546f6d7aca079e87290f3b0" ], "markers": "python_version >= '3.8'", - "version": "==0.14.1" + "version": "==0.14.2" }, "cachetools": { "hashes": [ @@ -568,70 +568,78 @@ }, "ddtrace": { "hashes": [ - "sha256:0019ca4349cfc50116d8c1194c38de58eb0b3abdd1b253e646f09f23b4afc54c", - "sha256:04351f2bad1a02c9bc7c8459e354baedd6bd4041dc142f611375be199912449c", - "sha256:09772884c2a95bfecaa6c05644d773dcb135f04340c561a7465d6b6d28b10edf", - "sha256:0a84d60ddc11c8de13900127c5d4ef8ad450b8dd06cc8db446f024b0c6d5015b", - "sha256:0ceabfd3bc9bc772a2dfe605c16d063bf91b4ac66c2033efc4211dfe3aa0243b", - "sha256:14360fc302489f2132ee18b5f6c24debbb21f955e3cb946050398d0c1595df17", - "sha256:15a37b22ffb20071ba20f8861eda9732de91a36664d7587ad59370d17aa79d85", - "sha256:173ae0a67c502add96c4d93b6c11db22de1879017318f75fc51a0f8897f2379c", - "sha256:1b1bd03574a089d9bd7ca9e43ac12a9c685e53a01e8037649837ca437a6b6d50", - "sha256:1e9b315eb03174ed85d6eead72364b7fd99b5e004e598bbf4670759659bf367b", - "sha256:22b42396bbf23cf7d30319936e3e62ba5b571692a62eef58e8d8a10e1b50c710", - "sha256:2a0a0dbe72234b73c176d4d91aa6ddccda89e89bd554cd910cadeb9dd4500670", - "sha256:2a5ec887bce8c2718f8a3f50fb2daa708aac973105735cd3f74d55f2ce69a220", - "sha256:2e2fc0bde27c86cf25bf53152b7107b1670d45ef6395a563160de56785ee4864", - "sha256:30a93b83e75bd25be1b20217295fb6e7000f2bf34ec32ff3abe00e3a7903b471", - "sha256:328b6dc3462ca83ce9d2171eed765d8b0ed2c54e75dde10b8d9d364a00f637a4", - "sha256:32e35dba7ff39b8cd30cf27079ae2442bf57fdd1fb2f8df6977b97e6d2088b52", - "sha256:34a74acf4cdc46f075948ecf59c7a2dfa8e6aea34f1f4cb29fd5c1a0f37c95e5", - "sha256:3bc030edeed2cf37cef67b9e7a9d00c2298ac779b091574899832a7938f67f53", - "sha256:41cea5049a0115660c9484b4156ad1151c51f4e6d92251922c54f7008c1954aa", - "sha256:41f174b33d2d944dca90ff5be0bec95c98606d82f954c3acd805e4f484d2ffd5", - "sha256:4422de0e528ba965324fe96670081731eec66db2742984e3893e642e8898fa23", - "sha256:4618d0fc75f9f7b794647b7ce794e4ddd74d377467bd4e5be4f548214205ca4d", - "sha256:500a40e5501f04340e4a50c31e10788a764278bd016e7c523c455980dc0f5cb1", - "sha256:5d2f9bdc53ee00c32f4451a368c29d0173231c195a521c12524e0dfbdddefdfa", - "sha256:620d543b2dce68b6bc6cf4524378e013244938b5ea0d9d1457ec351bb7f09009", - "sha256:62c7b96d7a5dcc54e469dfcfb61bccc53019010cbd1be51bdff48988fe715a83", - "sha256:641f77eed9d5ff5fbc3078b7b11e6210a0ee96d4d7599cccb1756961c4eef948", - "sha256:686c1ec683cb28e24d8746afd00e50cdd723ce19d86af26257174c58a06a28d6", - "sha256:68db9541c238b548e769358f255e072f6311078e423e051c29e78b5fad17af15", - "sha256:6adc5faf5807b7e17a320546b3a362e36ca7e53d862f07cb8c133ec5af3216ce", - "sha256:6fd148ade68f5321358adf52c1e9a5c9a82501c10886582e4e57fca6fdfbeeb7", - "sha256:70c03403704b20b38b27dfacfd9c071a779610049449577fceefaa4fcf7fa081", - "sha256:70e1227183cd07c247326da0db7b033110d6b05b4107ee5c8541a1bd859df8fd", - "sha256:74500caa641266d8e19e9ad4259b503fc97b0855bc144f8515caf9df96855f6f", - "sha256:8394525f0f588ebd8a6b90da9916088237fe00973f462ec59514e55a232072a7", - "sha256:859d10ecf4cd2b9a58c2af38cf95d77bbaaca3c8f2527f0120f796d8afd57c53", - "sha256:88cae70b85bb10fe2d7cfdf6fab7ccfb74163ebcc8f380c3fe4e59b7ed668d82", - "sha256:8c6a860655d4e2d0b6b8ad4db0a737731198c95ee7151262e2b415d7d4e77e0b", - "sha256:8d61d5d5b2be99c711dfb19d2e7d5b9864bb9a2b1051405bc38bc707b1c8dab2", - "sha256:8d99e32c28a75dfec09fe96ac99c9d7dfc7388c55a4549f43d925aa9110b8865", - "sha256:906a1b9aa3a9c1d3565c5381f1c8793dee7e2f80292c9aa285cfa6ebff3efbb9", - "sha256:92c6d5c706f1d64e240791a365ec319a3eb51acc293b40546c501e2188b77d09", - "sha256:968117040d319e10d4128314aebd3780dd06b4757c6d6b7de78036598ff9cbc8", - "sha256:9829e01e5401823976a9c413c4a19672fcf6538444421c67ab0e719b8d83235c", - "sha256:99db67cceaacd192596bd18de78ca90be19a3ecaa5875cc0014a72905bb622e7", - "sha256:a3d3a60dfcccadad9f97c7cb9cee803b68d1e2a9160cef44f4dc907b3be22a3b", - "sha256:a90f7cb8b55e257c2db4cba612b049eaf75d65db80b4fdb3e96af1ab906813d7", - "sha256:a91efe0a1a4f758f1ad74fa6cd238f2ed5e960f15695c1062effc11c4a6bd0eb", - "sha256:ba4f5a51a02a668d7c5cd7c7a30e48ab3d28c179e5729c5425e7349e74ce5060", - "sha256:bcbd3c75fc0ac2e2f48493b6451b8f34b55c28691011ddfcd9799730a461879b", - "sha256:c55c4970868996c1c1893259e94f0233dd87a3f5342ad27c711dba8a4a18071f", - "sha256:c62a0db263944a1b8b5676e0f33e216aae7febfa134b8c99025b6bf4a1aff8d3", - "sha256:c65185a80a95114d54310c329dca3ff6c8131cf0b770b3819b9aa627749bff3e", - "sha256:c9498e544f68cabaeb9aa9bdeb974405f7bced8a5c552d0f6477b686f6ffad96", - "sha256:caf4867f702ae6b83f27c797800309c7154a8cee00cf4b97c668d995f0cf9f0d", - "sha256:ccee8a36f6fef598161299111d845a83352c2d69646b2befdd6337b307dc9962", - "sha256:d6fdeb9e2260765b496f26dcafe747ab365ddc47637b697872757db430dde6be", - "sha256:f502695c8771ffecf52a27abaffc81c832a0146aab3c397a91abf6d7b09e9528", - "sha256:f67bdeffb774e7596c22f3d6307bad9d5cd9bd6b533392f4d98e91909c2ea02a" + "sha256:03086fa9bad36a4fef5fdf33d2a7a872e77d4d85742391c5ad47fd7a719f3f7f", + "sha256:03d9b8b64d98371823d22b14663a0704d263e5b67cef3590d4867db0cd1c5fcc", + "sha256:04199d69f9352e9463aa51fb4b08f11c7bfade0bf4f50dec597cf6577588c47c", + "sha256:08c95895cada1a6da8fdbe1c9a2e8eb2bb29e6df97cba33a1804c059605bf6ad", + "sha256:0a94c1b9645382b625e2d40158ae2c8035450d45456edc1c794152e24adb7572", + "sha256:0bccc189f799af9d25050fcbe626d10552e0a0d9989f853c195edbf49bd36199", + "sha256:11b4ee4627ea4df619f26d1947da83ea64b2f887eab790c56a8a1c866ac16a56", + "sha256:19e96324bb27af311c180013aedcc1aa1b341c281d902a7ca2c52a68804eb1ea", + "sha256:1d3d8412de4270044fdce3759eac0f4be93c60564fdf84b1c7d65a937d53720f", + "sha256:1f2587d376b9c35c6f7fabc5a1167c3eb1deb4726e801fdca6adcf2fb1c2c545", + "sha256:248279640bc696bc85ccec8137b3749b530ec77f3772a5ab1cf35dae9fc3185c", + "sha256:26c632967748f625e2bacf313eaea94b607fd08337aa94e5a3efc08a105e1646", + "sha256:2f3155ce3b36c616ff7ec9a66ddc3be57fba0d4703b439312b4e2d984f7bcc68", + "sha256:2f6a7b5812fb92d63a8f55ba24346b3d07ac76519250ed86b0bde98f8bb3e384", + "sha256:355dd017cf1b28e69df35996175bba5f7823e1d7368eec1b263b43a18976643e", + "sha256:3f5ac6c515ddee38c8ce7cc1227d5a88dfb715f8502ef952ee4356a311f13ba5", + "sha256:4050e59b42e340672523830e58702fdb2b8977a5f627c49047fb7e754bd15827", + "sha256:40bbc851c997577dc33aac65f77332c4dde8886c718b619772bd7e5823400155", + "sha256:45434237e8aaf6d4e8ed6dae746a9fd01eea162367a85c46ff588cf386cc7c75", + "sha256:49638d9e011fca10c44f227ca1e6051d95d84719179947f02a9ab7a898782340", + "sha256:4b878ba8c53c8894bf21eb7f71253af43da7ee2096f1b2d4ad93f7078fbd9e6a", + "sha256:507d4ebd509d407fe2133d19efc9923f551d4063ba8d9f62a4de7f1ac7dbe51a", + "sha256:514990e82f4da61b1c2f0c88f03f704701484f2982d6f514da368baa7a7f7121", + "sha256:57286262e57988582697d1a3d50ef86876d04b41ea2f420e67f37e5ca57dcf1e", + "sha256:587e3697986fece1a5bfc992d4e94fad6c527d48768d10675765b50ef22a260f", + "sha256:5bf285714e274c6fe6e776d753cd5cfdcbaa72542f2053e89b6eba87584db25e", + "sha256:5cc20ff3fb82bc614585ed32c4af81bf48b5fdfe4c474283df009982721c5552", + "sha256:5fc57b3adf0fe89be4a5c5870894933d01b2a8bed6e55c0d192612a47fc6fcf1", + "sha256:606bfcab7e9edb81a00f558cad76168b0f9bb995e9d3485b9297f7c18898c65c", + "sha256:61798b40fea57d7f59d7179e31b0f04b2e5901f06dc7b8abade3f72a50b4b119", + "sha256:619d3f615a4e1c85e021f9c058811d5e8e6491dd19cb3c594c877173abab9be7", + "sha256:64eaaf159ca310ce7dddde27c595503d1b9da9a1b6be668f411a2b02fba1ab29", + "sha256:650556e47507a1956f4790c5d2aa8c8e67161c9a6e2957a1b2c1271570079ff6", + "sha256:6a441ed49b5f673934508ea0bfd041c605939b4a56c989301af5d1d7b58b163f", + "sha256:6c70546e3f19f3173023d5d324d86f10bd113b45c3ba4214401eb35d36475576", + "sha256:749e5aa0cf2e3c0dc63b4b325c733d8d1505785fecf0194b5752d23adb6f4916", + "sha256:75e77c63e172d4a05f5b76b3b024ba28e2d9a1fbd931fc9b52f3726d8c9e78c3", + "sha256:7b7f860dfa8136f1953b0b129b7fafe7c60c0cf3ec4d0f7068f23f55e0567679", + "sha256:82a0b87cb214dfec2d25f70a2a18e89788bcc23a2f0f3cff1e750a842474c994", + "sha256:835d891b152e848bbdb0e2098c806a9344075bdf8d7ad1f84ab07fe3477a408c", + "sha256:87e5c897e3d0a60aba9beb36f0ef3db8477544b3f41dd990dbd89e505f1cb36c", + "sha256:8c2e23da18956c3f078931171c920c82792b5b8f5b779f2c9d743bcba6eebe6e", + "sha256:93408fb44289b318e6894635beb336a28ee4ce260b0db18b1391535bf833aeb1", + "sha256:93e52c2ab8ed4e112a19b93a56929b5eb3281ad6e5bc950e925d8a2eae3ab6a3", + "sha256:949f86469698650c2b4eab0881338408c1ac090df1dc792c0fc0b5fd928b39c8", + "sha256:9f61efa4bd35065b9d1ebcaa8d0c38aa07a69e815141bb78c29f47f9c366162e", + "sha256:a30bb5903c8bd695522a78d2cbc6b0e7189cd126fab63f3356acce8e78e453fa", + "sha256:a6f302e6dcb650cc37de3e5d329142c1adba095bd5072f5318ff599aded4f12b", + "sha256:a8a5f66e2cfce6868a625efb9e1954bc08b484e9edb67fc2d051c6a05c991bf7", + "sha256:aa32c91ced9d72bb4c18c59c81516a3f12e2b1f3b0511b54eb3b3b3b0a36c8a5", + "sha256:ae73f9efda7c230cb93efe1a28a097cab82f2792cae05c6739a500c64b98f512", + "sha256:b26d04c8f5d0c0fcb665fe1069e2b06ecb8f2cfbbacc255bb641e44a00e47390", + "sha256:b4558abcbc10e0b5c71cf54c490f5791163cd071e7bfdecce56db56f02ffd0a3", + "sha256:b633f149f83e1b8e376602c09ee99c4d6d264fa1510a7b61a937db7e631e1c69", + "sha256:b6f23d3a066513c3db1b2cbe0b63bda0629b8cdbfbb9ef34f45a0478688abe29", + "sha256:c6bc63fcc10c3128c91d245c5e677fd204ff10e67c3c75d26f28d34b6436bd15", + "sha256:c83f43e492cd16be18dbc0cab860bbd4066b6cb6bed374ce9eea4854fff56876", + "sha256:c8bd12d40a86c5567b9da4cc6180e75cd6da4fbfe3ee75d5e03197325912b986", + "sha256:d0aafd871773c2e28519040c69790fab38ca8731dde07cef64ffa3722253f07b", + "sha256:d5c20848ff667424c89995c2623538a215030992839c390fa5017278053d3cdd", + "sha256:d7abf200a82165d0b49abc94c070e2dc6083cd689c00f5ddb260b9609e3f3982", + "sha256:da95970736a920a6ce7a359d0adcb30b9711bbc21c2a1d898fdb8f87f9b0005d", + "sha256:dfbd8470ec8a81368f62847b90f9d0cdf804d311a737e4dc5127cbb6d87201b9", + "sha256:e1e250eb470930b65c1cbd197bac5dcc9d6e8e0a37bf52bd8de33b95e444c075", + "sha256:e71bd1567d157fa8bfb6f8ad97b3951d8cb892567d87e448c3f2bb94e9f405fe", + "sha256:e99efa02a24d0027fddb8434e6aceb2a6540362d24ce06f20da2ec582b80ffa6", + "sha256:ed9e06f51c97116b7fef5d5768e4defbc42927e4308272f2483ed24ae275e0f3", + "sha256:ff2eb2c9054d74c2d072215a3e01348c51915da940de71072ac187538273183c" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==2.18.1" + "version": "==2.19.1" }, "deprecated": { "hashes": [ @@ -817,11 +825,11 @@ }, "google-api-python-client": { "hashes": [ - "sha256:6352185c505e1f311f11b0b96c1b636dcb0fec82cd04b80ac5a671ac4dcab339", - "sha256:b809c111ded61716a9c1c7936e6899053f13bae3defcdfda904bd2ca68065b9c" + "sha256:55197f430f25c907394b44fa078545ffef89d33fd4dca501b7db9f0d8e224bd6", + "sha256:baef0bb631a60a0bd7c0bf12a5499e3a40cd4388484de7ee55c1950bf820a0cf" ], "markers": "python_version >= '3.7'", - "version": "==2.156.0" + "version": "==2.159.0" }, "google-auth": { "hashes": [ @@ -848,11 +856,11 @@ }, "google-cloud-firestore": { "hashes": [ - "sha256:1b2ce6e0b791aee89a1e4f072beba1012247e89baca361eed721fb467fe054b0", - "sha256:b49f0019d7bd0d4ab5972a4cff13994b0aabe72d24242200d904db2fb49df7f7" + "sha256:505ef6951b56ea91f6762d99b3429ca6def6dceb254b4ba1ffc85e69b71414d7", + "sha256:ad863be58667233921e02f0b81aa94a816f5e63a707cb33c97b1aa357a50566d" ], "markers": "python_version >= '3.7'", - "version": "==2.19.0" + "version": "==2.20.0" }, "google-cloud-storage": { "hashes": [ @@ -992,64 +1000,64 @@ }, "grpcio": { "hashes": [ - "sha256:025f790c056815b3bf53da850dd70ebb849fd755a4b1ac822cb65cd631e37d43", - "sha256:04cfd68bf4f38f5bb959ee2361a7546916bd9a50f78617a346b3aeb2b42e2161", - "sha256:0feb02205a27caca128627bd1df4ee7212db051019a9afa76f4bb6a1a80ca95e", - "sha256:1098f03dedc3b9810810568060dea4ac0822b4062f537b0f53aa015269be0a76", - "sha256:12941d533f3cd45d46f202e3667be8ebf6bcb3573629c7ec12c3e211d99cfccf", - "sha256:255b1635b0ed81e9f91da4fcc8d43b7ea5520090b9a9ad9340d147066d1d3613", - "sha256:298ee7f80e26f9483f0b6f94cc0a046caf54400a11b644713bb5b3d8eb387600", - "sha256:2c4cec6177bf325eb6faa6bd834d2ff6aa8bb3b29012cceb4937b86f8b74323c", - "sha256:2cc1fd04af8399971bcd4f43bd98c22d01029ea2e56e69c34daf2bf8470e47f5", - "sha256:334ab917792904245a028f10e803fcd5b6f36a7b2173a820c0b5b076555825e1", - "sha256:3522c77d7e6606d6665ec8d50e867f13f946a4e00c7df46768f1c85089eae515", - "sha256:37ea3be171f3cf3e7b7e412a98b77685eba9d4fd67421f4a34686a63a65d99f9", - "sha256:390eee4225a661c5cd133c09f5da1ee3c84498dc265fd292a6912b65c421c78c", - "sha256:3aed6544e4d523cd6b3119b0916cef3d15ef2da51e088211e4d1eb91a6c7f4f1", - "sha256:3ceb56c4285754e33bb3c2fa777d055e96e6932351a3082ce3559be47f8024f0", - "sha256:44a8502dd5de653ae6a73e2de50a401d84184f0331d0ac3daeb044e66d5c5054", - "sha256:4b177f5547f1b995826ef529d2eef89cca2f830dd8b2c99ffd5fde4da734ba73", - "sha256:4efac5481c696d5cb124ff1c119a78bddbfdd13fc499e3bc0ca81e95fc573684", - "sha256:52fbf85aa71263380d330f4fce9f013c0798242e31ede05fcee7fbe40ccfc20d", - "sha256:55857c71641064f01ff0541a1776bfe04a59db5558e82897d35a7793e525774c", - "sha256:66a24f3d45c33550703f0abb8b656515b0ab777970fa275693a2f6dc8e35f1c1", - "sha256:6ab2d912ca39c51f46baf2a0d92aa265aa96b2443266fc50d234fa88bf877d8e", - "sha256:77d65165fc35cff6e954e7fd4229e05ec76102d4406d4576528d3a3635fc6172", - "sha256:7dfc914cc31c906297b30463dde0b9be48e36939575eaf2a0a22a8096e69afe5", - "sha256:7f20ebec257af55694d8f993e162ddf0d36bd82d4e57f74b31c67b3c6d63d8b2", - "sha256:80af6f1e69c5e68a2be529990684abdd31ed6622e988bf18850075c81bb1ad6e", - "sha256:83bbf5807dc3ee94ce1de2dfe8a356e1d74101e4b9d7aa8c720cc4818a34aded", - "sha256:8720c25cd9ac25dd04ee02b69256d0ce35bf8a0f29e20577427355272230965a", - "sha256:8829924fffb25386995a31998ccbbeaa7367223e647e0122043dfc485a87c666", - "sha256:8a3869a6661ec8f81d93f4597da50336718bde9eb13267a699ac7e0a1d6d0bea", - "sha256:8cb620037a2fd9eeee97b4531880e439ebfcd6d7d78f2e7dcc3726428ab5ef63", - "sha256:919d7f18f63bcad3a0f81146188e90274fde800a94e35d42ffe9eadf6a9a6330", - "sha256:95c87ce2a97434dffe7327a4071839ab8e8bffd0054cc74cbe971fba98aedd60", - "sha256:963cc8d7d79b12c56008aabd8b457f400952dbea8997dd185f155e2f228db079", - "sha256:96f473cdacfdd506008a5d7579c9f6a7ff245a9ade92c3c0265eb76cc591914f", - "sha256:9d1fae6bbf0816415b81db1e82fb3bf56f7857273c84dcbe68cbe046e58e1ccd", - "sha256:a0c8ddabef9c8f41617f213e527254c41e8b96ea9d387c632af878d05db9229c", - "sha256:a1b988b40f2fd9de5c820f3a701a43339d8dcf2cb2f1ca137e2c02671cc83ac1", - "sha256:a47faedc9ea2e7a3b6569795c040aae5895a19dde0c728a48d3c5d7995fda385", - "sha256:a8040f85dcb9830d8bbb033ae66d272614cec6faceee88d37a88a9bd1a7a704e", - "sha256:b33bd114fa5a83f03ec6b7b262ef9f5cac549d4126f1dc702078767b10c46ed9", - "sha256:c08079b4934b0bf0a8847f42c197b1d12cba6495a3d43febd7e99ecd1cdc8d54", - "sha256:c28848761a6520c5c6071d2904a18d339a796ebe6b800adc8b3f474c5ce3c3ad", - "sha256:cb400138e73969eb5e0535d1d06cae6a6f7a15f2cc74add320e2130b8179211a", - "sha256:cbb5780e2e740b6b4f2d208e90453591036ff80c02cc605fea1af8e6fc6b1bbe", - "sha256:ccf2ebd2de2d6661e2520dae293298a3803a98ebfc099275f113ce1f6c2a80f1", - "sha256:d35740e3f45f60f3c37b1e6f2f4702c23867b9ce21c6410254c9c682237da68d", - "sha256:d99abcd61760ebb34bdff37e5a3ba333c5cc09feda8c1ad42547bea0416ada78", - "sha256:ddda1aa22495d8acd9dfbafff2866438d12faec4d024ebc2e656784d96328ad0", - "sha256:dffd29a2961f3263a16d73945b57cd44a8fd0b235740cb14056f0612329b345e", - "sha256:e4842e4872ae4ae0f5497bf60a0498fa778c192cc7a9e87877abd2814aca9475", - "sha256:e8dbe3e00771bfe3d04feed8210fc6617006d06d9a2679b74605b9fed3e8362c", - "sha256:ee2e743e51cb964b4975de572aa8fb95b633f496f9fcb5e257893df3be854746", - "sha256:eeb38ff04ab6e5756a2aef6ad8d94e89bb4a51ef96e20f45c44ba190fa0bcaad", - "sha256:f8261fa2a5f679abeb2a0a93ad056d765cdca1c47745eda3f2d87f874ff4b8c9" - ], - "markers": "python_version >= '3.8'", - "version": "==1.68.1" + "sha256:01f834732c22a130bdf3dc154d1053bdbc887eb3ccb7f3e6285cfbfc33d9d5cc", + "sha256:028337786f11fecb5d7b7fa660475a06aabf7e5e52b5ac2df47414878c0ce7ea", + "sha256:0470fa911c503af59ec8bc4c82b371ee4303ececbbdc055f55ce48e38b20fd67", + "sha256:0f0270bd9ffbff6961fe1da487bdcd594407ad390cc7960e738725d4807b18c4", + "sha256:1227ff7836f7b3a4ab04e5754f1d001fa52a730685d3dc894ed8bc262cc96c01", + "sha256:1514341def9c6ec4b7f0b9628be95f620f9d4b99331b7ef0a1845fd33d9b579c", + "sha256:1e925954b18d41aeb5ae250262116d0970893b38232689c4240024e4333ac084", + "sha256:1ee76cd7e2e49cf9264f6812d8c9ac1b85dda0eaea063af07292400f9191750e", + "sha256:1f03dc9b4da4c0dc8a1db7a5420f575251d7319b7a839004d8916257ddbe4816", + "sha256:200e48a6e7b00f804cf00a1c26292a5baa96507c7749e70a3ec10ca1a288936e", + "sha256:2060ca95a8db295ae828d0fc1c7f38fb26ccd5edf9aa51a0f44251f5da332e97", + "sha256:26c9a9c4ac917efab4704b18eed9082ed3b6ad19595f047e8173b5182fec0d5e", + "sha256:282f47d0928e40f25d007f24eb8fa051cb22551e3c74b8248bc9f9bea9c35fe0", + "sha256:2e52e107261fd8fa8fa457fe44bfadb904ae869d87c1280bf60f93ecd3e79278", + "sha256:316463c0832d5fcdb5e35ff2826d9aa3f26758d29cdfb59a368c1d6c39615a11", + "sha256:3629d8a8185f5139869a6a17865d03113a260e311e78fbe313f1a71603617589", + "sha256:3b75aea7c6cb91b341c85e7c1d9db1e09e1dd630b0717f836be94971e015031e", + "sha256:45a4704339b6e5b24b0e136dea9ad3815a94f30eb4f1e1d44c4ac484ef11d8dd", + "sha256:4ed866f9edb574fd9be71bf64c954ce1b88fc93b2a4cbf94af221e9426eb14d6", + "sha256:5494d0e52bf77a2f7eb17c6da662886ca0a731e56c1c85b93505bece8dc6cf4c", + "sha256:5ccbed100dc43704e94ccff9e07680b540d64e4cc89213ab2832b51b4f68a520", + "sha256:5cfd14175f9db33d4b74d63de87c64bb0ee29ce475ce3c00c01ad2a3dc2a9e51", + "sha256:60e5de105dc02832dc8f120056306d0ef80932bcf1c0e2b4ca3b676de6dc6505", + "sha256:7e76accf38808f5c5c752b0ab3fd919eb14ff8fafb8db520ad1cc12afff74de6", + "sha256:85d347cb8237751b23539981dbd2d9d8f6e9ff90082b427b13022b948eb6347a", + "sha256:87d222569273720366f68a99cb62e6194681eb763ee1d3b1005840678d4884f9", + "sha256:8b94e83f66dbf6fd642415faca0608590bc5e8d30e2c012b31d7d1b91b1de2fd", + "sha256:8cc614e895177ab7e4b70f154d1a7c97e152577ea101d76026d132b7aaba003b", + "sha256:8de1b192c29b8ce45ee26a700044717bcbbd21c697fa1124d440548964328561", + "sha256:9031069d36cb949205293cf0e243abd5e64d6c93e01b078c37921493a41b72dc", + "sha256:90b3646ced2eae3a0599658eeccc5ba7f303bf51b82514c50715bdd2b109e5ec", + "sha256:936fa44241b5379c5afc344e1260d467bee495747eaf478de825bab2791da6f5", + "sha256:a78a06911d4081a24a1761d16215a08e9b6d4d29cdbb7e427e6c7e17b06bcc5d", + "sha256:a7f4ed0dcf202a70fe661329f8874bc3775c14bb3911d020d07c82c766ce0eb1", + "sha256:b192b81076073ed46f4b4dd612b8897d9a1e39d4eabd822e5da7b38497ed77e1", + "sha256:b62b0f41e6e01a3e5082000b612064c87c93a49b05f7602fe1b7aa9fd5171a1d", + "sha256:b634851b92c090763dde61df0868c730376cdb73a91bcc821af56ae043b09596", + "sha256:b650f34aceac8b2d08a4c8d7dc3e8a593f4d9e26d86751ebf74ebf5107d927de", + "sha256:b7f693db593d6bf285e015d5538bf1c86cf9c60ed30b6f7da04a00ed052fe2f3", + "sha256:bf1f8be0da3fcdb2c1e9f374f3c2d043d606d69f425cd685110dd6d0d2d61258", + "sha256:bf5f680d3ed08c15330d7830d06bc65f58ca40c9999309517fd62880d70cb06e", + "sha256:c1fea55d26d647346acb0069b08dca70984101f2dc95066e003019207212e303", + "sha256:c5ba38aeac7a2fe353615c6b4213d1fbb3a3c34f86b4aaa8be08baaaee8cc56d", + "sha256:c9a281878feeb9ae26db0622a19add03922a028d4db684658f16d546601a4870", + "sha256:ca71d73a270dff052fe4edf74fef142d6ddd1f84175d9ac4a14b7280572ac519", + "sha256:cc89b6c29f3dccbe12d7a3b3f1b3999db4882ae076c1c1f6df231d55dbd767a5", + "sha256:cd7ea241b10bc5f0bb0f82c0d7896822b7ed122b3ab35c9851b440c1ccf81588", + "sha256:d5658c3c2660417d82db51e168b277e0ff036d0b0f859fa7576c0ffd2aec1442", + "sha256:db6f9fd2578dbe37db4b2994c94a1d9c93552ed77dca80e1657bb8a05b898b55", + "sha256:dc48f99cc05e0698e689b51a05933253c69a8c8559a47f605cff83801b03af0e", + "sha256:dc5a351927d605b2721cbb46158e431dd49ce66ffbacb03e709dc07a491dde35", + "sha256:dd034d68a2905464c49479b0c209c773737a4245d616234c79c975c7c90eca03", + "sha256:f79e05f5bbf551c4057c227d1b041ace0e78462ac8128e2ad39ec58a382536d2", + "sha256:fb9302afc3a0e4ba0b225cd651ef8e478bf0070cf11a529175caecd5ea2474e7", + "sha256:fc18a4de8c33491ad6f70022af5c460b39611e39578a4d84de0fe92f12d5d47b" + ], + "markers": "python_version >= '3.8'", + "version": "==1.69.0" }, "grpcio-status": { "hashes": [ @@ -1182,6 +1190,14 @@ "markers": "python_version >= '3.7'", "version": "==1.0.1" }, + "legacy-cgi": { + "hashes": [ + "sha256:9952471ceb304043b104c22d00b4f333cac27a6abe446d8a528fc437cf13c85f", + "sha256:a7b83afb1baf6ebeb56522537c5943ef9813cf933f6715e88a803f7edbce0bff" + ], + "markers": "python_version >= '3.10'", + "version": "==2.6.2" + }, "mako": { "hashes": [ "sha256:42f48953c7eb91332040ff567eb7eea69b22e7a4affbc5ba8e845e8f730f6627", @@ -1275,12 +1291,12 @@ }, "more-itertools": { "hashes": [ - "sha256:037b0d3203ce90cca8ab1defbbdac29d5f993fc20131f3664dc8d6acfa872aef", - "sha256:5482bfef7849c25dc3c6dd53a6173ae4795da2a41a80faea6700d9f5846c5da6" + "sha256:2cd7fad1009c31cc9fb6a035108509e6547547a7a738374f10bd49a09eb3ee3b", + "sha256:6eb054cb4b6db1473f6e15fcc676a08e4732548acd47c708f0e179c2c7c01e89" ], "index": "pypi", - "markers": "python_version >= '3.8'", - "version": "==10.5.0" + "markers": "python_version >= '3.9'", + "version": "==10.6.0" }, "msgpack": { "hashes": [ @@ -1839,11 +1855,11 @@ }, "pycron": { "hashes": [ - "sha256:6de8a555f721c74aa0bb681071a97da3d784ebf8ccea1d2bb9a3e66460b87da2", - "sha256:bf676a66b8dcf69edf1d3fd1d8f3f2b9468a2a007012c89a14e9d087d3f76198" + "sha256:114c71bc61002b850a416e33e72a8c6de75b9f5c4228e86d7babd8a7ea232d94", + "sha256:30e4a01889dfb471e80cc76a5c0ab87e675146a7f6d2d66a2e4bdb4e2975ef3d" ], - "markers": "python_version < '3.13' and python_version >= '3.9'", - "version": "==3.1.1" + "markers": "python_version >= '3.9' and python_version < '4.0'", + "version": "==3.1.2" }, "pydantic": { "extras": [ @@ -1899,11 +1915,11 @@ }, "pygments": { "hashes": [ - "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", - "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" + "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", + "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c" ], "markers": "python_version >= '3.8'", - "version": "==2.18.0" + "version": "==2.19.1" }, "pyjwt": { "extras": [ @@ -2126,28 +2142,28 @@ }, "s3transfer": { "hashes": [ - "sha256:244a76a24355363a68164241438de1b72f8781664920260c48465896b712a41e", - "sha256:29edc09801743c21eb5ecbc617a152df41d3c287f67b615f73e5f750583666a7" + "sha256:3f25c900a367c8b7f7d8f9c34edc87e300bde424f779dc9f0a8ae4f9df9264f6", + "sha256:8fa0aa48177be1f3425176dfe1ab85dcd3d962df603c3dbfc585e6bf857ef0ff" ], "markers": "python_version >= '3.8'", - "version": "==0.10.4" + "version": "==0.11.1" }, "sentry-sdk": { "hashes": [ - "sha256:467df6e126ba242d39952375dd816fbee0f217d119bf454a8ce74cf1e7909e8d", - "sha256:ebdc08228b4d131128e568d696c210d846e5b9d70aa0327dec6b1272d9d40b84" + "sha256:afa82713a92facf847df3c6f63cec71eb488d826a50965def3d7722aa6f0fdab", + "sha256:c359a1edf950eb5e80cffd7d9111f3dbeef57994cb4415df37d39fda2cf22364" ], "index": "pypi", "markers": "python_version >= '3.6'", - "version": "==2.19.2" + "version": "==2.20.0" }, "setuptools": { "hashes": [ - "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6", - "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d" + "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6", + "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3" ], "markers": "python_version >= '3.9'", - "version": "==75.6.0" + "version": "==75.8.0" }, "shellingham": { "hashes": [ @@ -2245,12 +2261,12 @@ }, "structlog": { "hashes": [ - "sha256:597f61e80a91cc0749a9fd2a098ed76715a1c8a01f73e336b746504d1aad7610", - "sha256:b27bfecede327a6d2da5fbc96bd859f114ecc398a6389d664f62085ee7ae6fc4" + "sha256:2ef2a572e0e27f09664965d31a576afe64e46ac6084ef5cec3c2b8cd6e4e3ad3", + "sha256:843fe4f254540329f380812cbe612e1af5ec5b8172205ae634679cd35a6d6321" ], "index": "pypi", "markers": "python_version >= '3.8'", - "version": "==24.4.0" + "version": "==25.1.0" }, "taskiq": { "extras": [ @@ -2428,80 +2444,80 @@ }, "watchfiles": { "hashes": [ - "sha256:0179252846be03fa97d4d5f8233d1c620ef004855f0717712ae1c558f1974a16", - "sha256:06ce08549e49ba69ccc36fc5659a3d0ff4e3a07d542b895b8a9013fcab46c2dc", - "sha256:0b90651b4cf9e158d01faa0833b073e2e37719264bcee3eac49fc3c74e7d304b", - "sha256:0d1ec043f02ca04bf21b1b32cab155ce90c651aaf5540db8eb8ad7f7e645cba8", - "sha256:0fe4e740ea94978b2b2ab308cbf9270a246bcbb44401f77cc8740348cbaeac3d", - "sha256:127de3883bdb29dbd3b21f63126bb8fa6e773b74eaef46521025a9ce390e1073", - "sha256:1550be1a5cb3be08a3fb84636eaafa9b7119b70c71b0bed48726fd1d5aa9b868", - "sha256:160eff7d1267d7b025e983ca8460e8cc67b328284967cbe29c05f3c3163711a3", - "sha256:16db2d7e12f94818cbf16d4c8938e4d8aaecee23826344addfaaa671a1527b07", - "sha256:1c6cf7709ed3e55704cc06f6e835bf43c03bc8e3cb8ff946bf69a2e0a78d9d77", - "sha256:1da46bb1eefb5a37a8fb6fd52ad5d14822d67c498d99bda8754222396164ae42", - "sha256:1df924ba82ae9e77340101c28d56cbaff2c991bd6fe8444a545d24075abb0a87", - "sha256:1e263cc718545b7f897baeac1f00299ab6fabe3e18caaacacb0edf6d5f35513c", - "sha256:228e2247de583475d4cebf6b9af5dc9918abb99d1ef5ee737155bb39fb33f3c0", - "sha256:275c1b0e942d335fccb6014d79267d1b9fa45b5ac0639c297f1e856f2f532552", - "sha256:29b9cb35b7f290db1c31fb2fdf8fc6d3730cfa4bca4b49761083307f441cac5a", - "sha256:2b4691234d31686dca133c920f94e478b548a8e7c750f28dbbc2e4333e0d3da9", - "sha256:2b961b86cd3973f5822826017cad7f5a75795168cb645c3a6b30c349094e02e3", - "sha256:2dcc3f60c445f8ce14156854a072ceb36b83807ed803d37fdea2a50e898635d6", - "sha256:2f492d2907263d6d0d52f897a68647195bc093dafed14508a8d6817973586b6b", - "sha256:310505ad305e30cb6c5f55945858cdbe0eb297fc57378f29bacceb534ac34199", - "sha256:34e87c7b3464d02af87f1059fedda5484e43b153ef519e4085fe1a03dd94801e", - "sha256:418c5ce332f74939ff60691e5293e27c206c8164ce2b8ce0d9abf013003fb7fe", - "sha256:46e86ed457c3486080a72bc837300dd200e18d08183f12b6ca63475ab64ed651", - "sha256:48681c86f2cb08348631fed788a116c89c787fdf1e6381c5febafd782f6c3b44", - "sha256:489b80812f52a8d8c7b0d10f0d956db0efed25df2821c7a934f6143f76938bd6", - "sha256:48c9f3bc90c556a854f4cab6a79c16974099ccfa3e3e150673d82d47a4bc92c9", - "sha256:49bc1bc26abf4f32e132652f4b3bfeec77d8f8f62f57652703ef127e85a3e38d", - "sha256:52bb50a4c4ca2a689fdba84ba8ecc6a4e6210f03b6af93181bb61c4ec3abaf86", - "sha256:5691340f259b8f76b45fb31b98e594d46c36d1dc8285efa7975f7f50230c9093", - "sha256:62691f1c0894b001c7cde1195c03b7801aaa794a837bd6eef24da87d1542838d", - "sha256:632a52dcaee44792d0965c17bdfe5dc0edad5b86d6a29e53d6ad4bf92dc0ff49", - "sha256:65ab1fb635476f6170b07e8e21db0424de94877e4b76b7feabfe11f9a5fc12b5", - "sha256:6a5bc3ca468bb58a2ef50441f953e1f77b9a61bd1b8c347c8223403dc9b4ac9a", - "sha256:6a76494d2c5311584f22416c5a87c1e2cb954ff9b5f0988027bc4ef2a8a67181", - "sha256:6f8dc09ae69af50bead60783180f656ad96bd33ffbf6e7a6fce900f6d53b08f1", - "sha256:703aa5e50e465be901e0e0f9d5739add15e696d8c26c53bc6fc00eb65d7b9469", - "sha256:713f67132346bdcb4c12df185c30cf04bdf4bf6ea3acbc3ace0912cab6b7cb8c", - "sha256:75d3bcfa90454dba8df12adc86b13b6d85fda97d90e708efc036c2760cc6ba44", - "sha256:7ca05cacf2e5c4a97d02a2878a24020daca21dbb8823b023b978210a75c79098", - "sha256:80bf4b459d94a0387617a1b499f314aa04d8a64b7a0747d15d425b8c8b151da0", - "sha256:84fac88278f42d61c519a6c75fb5296fd56710b05bbdcc74bdf85db409a03780", - "sha256:889a37e2acf43c377b5124166bece139b4c731b61492ab22e64d371cce0e6e80", - "sha256:8af4b582d5fc1b8465d1d2483e5e7b880cc1a4e99f6ff65c23d64d070867ac58", - "sha256:90b0fe1fcea9bd6e3084b44875e179b4adcc4057a3b81402658d0eb58c98edf8", - "sha256:93436ed550e429da007fbafb723e0769f25bae178fbb287a94cb4ccdf42d3af3", - "sha256:995c374e86fa82126c03c5b4630c4e312327ecfe27761accb25b5e1d7ab50ec8", - "sha256:9af037d3df7188ae21dc1c7624501f2f90d81be6550904e07869d8d0e6766655", - "sha256:9e080cf917b35b20c889225a13f290f2716748362f6071b859b60b8847a6aa43", - "sha256:a2ec98e31e1844eac860e70d9247db9d75440fc8f5f679c37d01914568d18721", - "sha256:abd85de513eb83f5ec153a802348e7a5baa4588b818043848247e3e8986094e8", - "sha256:ac1be85fe43b4bf9a251978ce5c3bb30e1ada9784290441f5423a28633a958a7", - "sha256:be37f9b1f8934cd9e7eccfcb5612af9fb728fecbe16248b082b709a9d1b348bf", - "sha256:bfcae6aecd9e0cb425f5145afee871465b98b75862e038d42fe91fd753ddd780", - "sha256:c05b021f7b5aa333124f2a64d56e4cb9963b6efdf44e8d819152237bbd93ba15", - "sha256:c14a07bdb475eb696f85c715dbd0f037918ccbb5248290448488a0b4ef201aad", - "sha256:c18f3502ad0737813c7dad70e3e1cc966cc147fbaeef47a09463bbffe70b0a00", - "sha256:c2e9fe695ff151b42ab06501820f40d01310fbd58ba24da8923ace79cf6d702d", - "sha256:c68be72b1666d93b266714f2d4092d78dc53bd11cf91ed5a3c16527587a52e29", - "sha256:ca94c85911601b097d53caeeec30201736ad69a93f30d15672b967558df02885", - "sha256:cf745cbfad6389c0e331786e5fe9ae3f06e9d9c2ce2432378e1267954793975c", - "sha256:d9dd2b89a16cf7ab9c1170b5863e68de6bf83db51544875b25a5f05a7269e678", - "sha256:ddff3f8b9fa24a60527c137c852d0d9a7da2a02cf2151650029fdc97c852c974", - "sha256:e153a690b7255c5ced17895394b4f109d5dcc2a4f35cb809374da50f0e5c456a", - "sha256:ea2b51c5f38bad812da2ec0cd7eec09d25f521a8b6b6843cbccedd9a1d8a5c15", - "sha256:ef9ec8068cf23458dbf36a08e0c16f0a2df04b42a8827619646637be1769300a", - "sha256:f280b02827adc9d87f764972fbeb701cf5611f80b619c20568e1982a277d6146", - "sha256:f3ff7da165c99a5412fe5dd2304dd2dbaaaa5da718aad942dcb3a178eaa70c56", - "sha256:f58d3bfafecf3d81c15d99fc0ecf4319e80ac712c77cf0ce2661c8cf8bf84066", - "sha256:f79fe7993e230a12172ce7d7c7db061f046f672f2b946431c81aff8f60b2758b", - "sha256:ffe709b1d0bc2e9921257569675674cafb3a5f8af689ab9f3f2b3f88775b960f" + "sha256:02a526ee5b5a09e8168314c905fc545c9bc46509896ed282aeb5a8ba9bd6ca27", + "sha256:05d341c71f3d7098920f8551d4df47f7b57ac5b8dad56558064c3431bdfc0b74", + "sha256:076f293100db3b0b634514aa0d294b941daa85fc777f9c698adb1009e5aca0b1", + "sha256:0799ae68dfa95136dde7c472525700bd48777875a4abb2ee454e3ab18e9fc712", + "sha256:0986902677a1a5e6212d0c49b319aad9cc48da4bd967f86a11bde96ad9676ca1", + "sha256:0bc80d91ddaf95f70258cf78c471246846c1986bcc5fd33ccc4a1a67fcb40f9a", + "sha256:13c2ce7b72026cfbca120d652f02c7750f33b4c9395d79c9790b27f014c8a5a2", + "sha256:1941b4e39de9b38b868a69b911df5e89dc43767feeda667b40ae032522b9b5f1", + "sha256:1eacd91daeb5158c598fe22d7ce66d60878b6294a86477a4715154990394c9b3", + "sha256:229e6ec880eca20e0ba2f7e2249c85bae1999d330161f45c78d160832e026ee2", + "sha256:22bb55a7c9e564e763ea06c7acea24fc5d2ee5dfc5dafc5cfbedfe58505e9f90", + "sha256:278aaa395f405972e9f523bd786ed59dfb61e4b827856be46a42130605fd0899", + "sha256:2a9f93f8439639dc244c4d2902abe35b0279102bca7bbcf119af964f51d53c19", + "sha256:308ac265c56f936636e3b0e3f59e059a40003c655228c131e1ad439957592303", + "sha256:31f1a379c9dcbb3f09cf6be1b7e83b67c0e9faabed0471556d9438a4a4e14202", + "sha256:32b026a6ab64245b584acf4931fe21842374da82372d5c039cba6bf99ef722f3", + "sha256:342622287b5604ddf0ed2d085f3a589099c9ae8b7331df3ae9845571586c4f3d", + "sha256:39f4914548b818540ef21fd22447a63e7be6e24b43a70f7642d21f1e73371590", + "sha256:3f68d8e9d5a321163ddacebe97091000955a1b74cd43724e346056030b0bacee", + "sha256:43b168bba889886b62edb0397cab5b6490ffb656ee2fcb22dec8bfeb371a9e12", + "sha256:47eb32ef8c729dbc4f4273baece89398a4d4b5d21a1493efea77a17059f4df8a", + "sha256:4810ea2ae622add560f4aa50c92fef975e475f7ac4900ce5ff5547b2434642d8", + "sha256:4e997802d78cdb02623b5941830ab06f8860038faf344f0d288d325cc9c5d2ff", + "sha256:4ebbeca9360c830766b9f0df3640b791be569d988f4be6c06d6fae41f187f105", + "sha256:4f8c4998506241dedf59613082d1c18b836e26ef2a4caecad0ec41e2a15e4226", + "sha256:55ccfd27c497b228581e2838d4386301227fc0cb47f5a12923ec2fe4f97b95af", + "sha256:5717021b199e8353782dce03bd8a8f64438832b84e2885c4a645f9723bf656d9", + "sha256:5c11ea22304d17d4385067588123658e9f23159225a27b983f343fcffc3e796a", + "sha256:5e0227b8ed9074c6172cf55d85b5670199c99ab11fd27d2c473aa30aec67ee42", + "sha256:62c9953cf85529c05b24705639ffa390f78c26449e15ec34d5339e8108c7c407", + "sha256:6ba473efd11062d73e4f00c2b730255f9c1bdd73cd5f9fe5b5da8dbd4a717205", + "sha256:740d103cd01458f22462dedeb5a3382b7f2c57d07ff033fbc9465919e5e1d0f3", + "sha256:74cb3ca19a740be4caa18f238298b9d472c850f7b2ed89f396c00a4c97e2d9ff", + "sha256:7b75fee5a16826cf5c46fe1c63116e4a156924d668c38b013e6276f2582230f0", + "sha256:7cf684aa9bba4cd95ecb62c822a56de54e3ae0598c1a7f2065d51e24637a3c5d", + "sha256:8012bd820c380c3d3db8435e8cf7592260257b378b649154a7948a663b5f84e9", + "sha256:857f5fc3aa027ff5e57047da93f96e908a35fe602d24f5e5d8ce64bf1f2fc733", + "sha256:8b1f135238e75d075359cf506b27bf3f4ca12029c47d3e769d8593a2024ce161", + "sha256:8d0d0630930f5cd5af929040e0778cf676a46775753e442a3f60511f2409f48f", + "sha256:90192cdc15ab7254caa7765a98132a5a41471cf739513cc9bcf7d2ffcc0ec7b2", + "sha256:95b42cac65beae3a362629950c444077d1b44f1790ea2772beaea95451c086bb", + "sha256:9745a4210b59e218ce64c91deb599ae8775c8a9da4e95fb2ee6fe745fc87d01a", + "sha256:9d1ef56b56ed7e8f312c934436dea93bfa3e7368adfcf3df4c0da6d4de959a1e", + "sha256:9eea33ad8c418847dd296e61eb683cae1c63329b6d854aefcd412e12d94ee235", + "sha256:9f25d0ba0fe2b6d2c921cf587b2bf4c451860086534f40c384329fb96e2044d1", + "sha256:9fe37a2de80aa785d340f2980276b17ef697ab8db6019b07ee4fd28a8359d2f3", + "sha256:a38320582736922be8c865d46520c043bff350956dfc9fbaee3b2df4e1740a4b", + "sha256:a462490e75e466edbb9fc4cd679b62187153b3ba804868452ef0577ec958f5ff", + "sha256:a5ae5706058b27c74bac987d615105da17724172d5aaacc6c362a40599b6de43", + "sha256:aa216f87594f951c17511efe5912808dfcc4befa464ab17c98d387830ce07b60", + "sha256:ab0311bb2ffcd9f74b6c9de2dda1612c13c84b996d032cd74799adb656af4e8b", + "sha256:ab594e75644421ae0a2484554832ca5895f8cab5ab62de30a1a57db460ce06c6", + "sha256:aee397456a29b492c20fda2d8961e1ffb266223625346ace14e4b6d861ba9c80", + "sha256:b045c800d55bc7e2cadd47f45a97c7b29f70f08a7c2fa13241905010a5493f94", + "sha256:b77d5622ac5cc91d21ae9c2b284b5d5c51085a0bdb7b518dba263d0af006132c", + "sha256:ba5bb3073d9db37c64520681dd2650f8bd40902d991e7b4cfaeece3e32561d08", + "sha256:bdef5a1be32d0b07dcea3318a0be95d42c98ece24177820226b56276e06b63b0", + "sha256:c2acfa49dd0ad0bf2a9c0bb9a985af02e89345a7189be1efc6baa085e0f72d7c", + "sha256:c7cce76c138a91e720d1df54014a047e680b652336e1b73b8e3ff3158e05061e", + "sha256:cc27a65069bcabac4552f34fd2dce923ce3fcde0721a16e4fb1b466d63ec831f", + "sha256:cdbd912a61543a36aef85e34f212e5d2486e7c53ebfdb70d1e0b060cc50dd0bf", + "sha256:cdcc92daeae268de1acf5b7befcd6cfffd9a047098199056c72e4623f531de18", + "sha256:d3452c1ec703aa1c61e15dfe9d482543e4145e7c45a6b8566978fbb044265a21", + "sha256:d6097538b0ae5c1b88c3b55afa245a66793a8fec7ada6755322e465fb1a0e8cc", + "sha256:d8d3d9203705b5797f0af7e7e5baa17c8588030aaadb7f6a86107b7247303817", + "sha256:e0611d244ce94d83f5b9aff441ad196c6e21b55f77f3c47608dcf651efe54c4a", + "sha256:f12969a3765909cf5dc1e50b2436eb2c0e676a3c75773ab8cc3aa6175c16e902", + "sha256:f44a39aee3cbb9b825285ff979ab887a25c5d336e5ec3574f1506a4671556a8d", + "sha256:f9ce064e81fe79faa925ff03b9f4c1a98b0bbb4a1b8c1b015afa93030cb21a49", + "sha256:fb2c46e275fbb9f0c92e7654b231543c7bbfa1df07cdc4b99fa73bedfde5c844", + "sha256:fc2eb5d14a8e0d5df7b36288979176fbb39672d45184fc4b1c004d7c3ce29317" ], "markers": "python_version >= '3.9'", - "version": "==1.0.3" + "version": "==1.0.4" }, "websockets": { "hashes": [ @@ -2580,74 +2596,88 @@ }, "wrapt": { "hashes": [ - "sha256:0229b247b0fc7dee0d36176cbb79dbaf2a9eb7ecc50ec3121f40ef443155fb1d", - "sha256:0698d3a86f68abc894d537887b9bbf84d29bcfbc759e23f4644be27acf6da301", - "sha256:0a0a1a1ec28b641f2a3a2c35cbe86c00051c04fffcfcc577ffcdd707df3f8635", - "sha256:0b48554952f0f387984da81ccfa73b62e52817a4386d070c75e4db7d43a28c4a", - "sha256:0f2a28eb35cf99d5f5bd12f5dd44a0f41d206db226535b37b0c60e9da162c3ed", - "sha256:140ea00c87fafc42739bd74a94a5a9003f8e72c27c47cd4f61d8e05e6dec8721", - "sha256:16187aa2317c731170a88ef35e8937ae0f533c402872c1ee5e6d079fcf320801", - "sha256:17fcf043d0b4724858f25b8826c36e08f9fb2e475410bece0ec44a22d533da9b", - "sha256:18b956061b8db634120b58f668592a772e87e2e78bc1f6a906cfcaa0cc7991c1", - "sha256:2399408ac33ffd5b200480ee858baa58d77dd30e0dd0cab6a8a9547135f30a88", - "sha256:2a0c23b8319848426f305f9cb0c98a6e32ee68a36264f45948ccf8e7d2b941f8", - "sha256:2dfb7cff84e72e7bf975b06b4989477873dcf160b2fd89959c629535df53d4e0", - "sha256:2f495b6754358979379f84534f8dd7a43ff8cff2558dcdea4a148a6e713a758f", - "sha256:33539c6f5b96cf0b1105a0ff4cf5db9332e773bb521cc804a90e58dc49b10578", - "sha256:3c34f6896a01b84bab196f7119770fd8466c8ae3dfa73c59c0bb281e7b588ce7", - "sha256:498fec8da10e3e62edd1e7368f4b24aa362ac0ad931e678332d1b209aec93045", - "sha256:4d63f4d446e10ad19ed01188d6c1e1bb134cde8c18b0aa2acfd973d41fcc5ada", - "sha256:4e4b4385363de9052dac1a67bfb535c376f3d19c238b5f36bddc95efae15e12d", - "sha256:4e547b447073fc0dbfcbff15154c1be8823d10dab4ad401bdb1575e3fdedff1b", - "sha256:4f643df3d4419ea3f856c5c3f40fec1d65ea2e89ec812c83f7767c8730f9827a", - "sha256:4f763a29ee6a20c529496a20a7bcb16a73de27f5da6a843249c7047daf135977", - "sha256:5ae271862b2142f4bc687bdbfcc942e2473a89999a54231aa1c2c676e28f29ea", - "sha256:5d8fd17635b262448ab8f99230fe4dac991af1dabdbb92f7a70a6afac8a7e346", - "sha256:69c40d4655e078ede067a7095544bcec5a963566e17503e75a3a3e0fe2803b13", - "sha256:69d093792dc34a9c4c8a70e4973a3361c7a7578e9cd86961b2bbf38ca71e4e22", - "sha256:6a9653131bda68a1f029c52157fd81e11f07d485df55410401f745007bd6d339", - "sha256:6ff02a91c4fc9b6a94e1c9c20f62ea06a7e375f42fe57587f004d1078ac86ca9", - "sha256:714c12485aa52efbc0fc0ade1e9ab3a70343db82627f90f2ecbc898fdf0bb181", - "sha256:7264cbb4a18dc4acfd73b63e4bcfec9c9802614572025bdd44d0721983fc1d9c", - "sha256:73a96fd11d2b2e77d623a7f26e004cc31f131a365add1ce1ce9a19e55a1eef90", - "sha256:74bf625b1b4caaa7bad51d9003f8b07a468a704e0644a700e936c357c17dd45a", - "sha256:81b1289e99cf4bad07c23393ab447e5e96db0ab50974a280f7954b071d41b489", - "sha256:8425cfce27b8b20c9b89d77fb50e368d8306a90bf2b6eef2cdf5cd5083adf83f", - "sha256:875d240fdbdbe9e11f9831901fb8719da0bd4e6131f83aa9f69b96d18fae7504", - "sha256:879591c2b5ab0a7184258274c42a126b74a2c3d5a329df16d69f9cee07bba6ea", - "sha256:89fc28495896097622c3fc238915c79365dd0ede02f9a82ce436b13bd0ab7569", - "sha256:8a5e7cc39a45fc430af1aefc4d77ee6bad72c5bcdb1322cfde852c15192b8bd4", - "sha256:8f8909cdb9f1b237786c09a810e24ee5e15ef17019f7cecb207ce205b9b5fcce", - "sha256:914f66f3b6fc7b915d46c1cc424bc2441841083de01b90f9e81109c9759e43ab", - "sha256:92a3d214d5e53cb1db8b015f30d544bc9d3f7179a05feb8f16df713cecc2620a", - "sha256:948a9bd0fb2c5120457b07e59c8d7210cbc8703243225dbd78f4dfc13c8d2d1f", - "sha256:9c900108df470060174108012de06d45f514aa4ec21a191e7ab42988ff42a86c", - "sha256:9f2939cd4a2a52ca32bc0b359015718472d7f6de870760342e7ba295be9ebaf9", - "sha256:a4192b45dff127c7d69b3bdfb4d3e47b64179a0b9900b6351859f3001397dabf", - "sha256:a8fc931382e56627ec4acb01e09ce66e5c03c384ca52606111cee50d931a342d", - "sha256:ad47b095f0bdc5585bced35bd088cbfe4177236c7df9984b3cc46b391cc60627", - "sha256:b1ca5f060e205f72bec57faae5bd817a1560fcfc4af03f414b08fa29106b7e2d", - "sha256:ba1739fb38441a27a676f4de4123d3e858e494fac05868b7a281c0a383c098f4", - "sha256:baa7ef4e0886a6f482e00d1d5bcd37c201b383f1d314643dfb0367169f94f04c", - "sha256:bb90765dd91aed05b53cd7a87bd7f5c188fcd95960914bae0d32c5e7f899719d", - "sha256:bc7f729a72b16ee21795a943f85c6244971724819819a41ddbaeb691b2dd85ad", - "sha256:bdf62d25234290db1837875d4dceb2151e4ea7f9fff2ed41c0fde23ed542eb5b", - "sha256:c30970bdee1cad6a8da2044febd824ef6dc4cc0b19e39af3085c763fdec7de33", - "sha256:d2c63b93548eda58abf5188e505ffed0229bf675f7c3090f8e36ad55b8cbc371", - "sha256:d751300b94e35b6016d4b1e7d0e7bbc3b5e1751e2405ef908316c2a9024008a1", - "sha256:da427d311782324a376cacb47c1a4adc43f99fd9d996ffc1b3e8529c4074d393", - "sha256:daba396199399ccabafbfc509037ac635a6bc18510ad1add8fd16d4739cdd106", - "sha256:e185ec6060e301a7e5f8461c86fb3640a7beb1a0f0208ffde7a65ec4074931df", - "sha256:e4a557d97f12813dc5e18dad9fa765ae44ddd56a672bb5de4825527c847d6379", - "sha256:e5ed16d95fd142e9c72b6c10b06514ad30e846a0d0917ab406186541fe68b451", - "sha256:e711fc1acc7468463bc084d1b68561e40d1eaa135d8c509a65dd534403d83d7b", - "sha256:f28b29dc158ca5d6ac396c8e0a2ef45c4e97bb7e65522bfc04c989e6fe814575", - "sha256:f335579a1b485c834849e9075191c9898e0731af45705c2ebf70e0cd5d58beed", - "sha256:fce6fee67c318fdfb7f285c29a82d84782ae2579c0e1b385b7f36c6e8074fffb", - "sha256:fd136bb85f4568fffca995bd3c8d52080b1e5b225dbf1c2b17b66b4c5fa02838" - ], - "markers": "python_version >= '3.8'", - "version": "==1.17.0" + "sha256:08e7ce672e35efa54c5024936e559469436f8b8096253404faeb54d2a878416f", + "sha256:0a6e821770cf99cc586d33833b2ff32faebdbe886bd6322395606cf55153246c", + "sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a", + "sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b", + "sha256:13e6afb7fe71fe7485a4550a8844cc9ffbe263c0f1a1eea569bc7091d4898555", + "sha256:1473400e5b2733e58b396a04eb7f35f541e1fb976d0c0724d0223dd607e0f74c", + "sha256:18983c537e04d11cf027fbb60a1e8dfd5190e2b60cc27bc0808e653e7b218d1b", + "sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6", + "sha256:1e1fe0e6ab7775fd842bc39e86f6dcfc4507ab0ffe206093e76d61cde37225c8", + "sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662", + "sha256:2696993ee1eebd20b8e4ee4356483c4cb696066ddc24bd70bcbb80fa56ff9061", + "sha256:35621ae4c00e056adb0009f8e86e28eb4a41a4bfa8f9bfa9fca7d343fe94f998", + "sha256:36ccae62f64235cf8ddb682073a60519426fdd4725524ae38874adf72b5f2aeb", + "sha256:3cedbfa9c940fdad3e6e941db7138e26ce8aad38ab5fe9dcfadfed9db7a54e62", + "sha256:3d57c572081fed831ad2d26fd430d565b76aa277ed1d30ff4d40670b1c0dd984", + "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392", + "sha256:4011d137b9955791f9084749cba9a367c68d50ab8d11d64c50ba1688c9b457f2", + "sha256:40d615e4fe22f4ad3528448c193b218e077656ca9ccb22ce2cb20db730f8d306", + "sha256:410a92fefd2e0e10d26210e1dfb4a876ddaf8439ef60d6434f21ef8d87efc5b7", + "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3", + "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9", + "sha256:49703ce2ddc220df165bd2962f8e03b84c89fee2d65e1c24a7defff6f988f4d6", + "sha256:4a721d3c943dae44f8e243b380cb645a709ba5bd35d3ad27bc2ed947e9c68192", + "sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317", + "sha256:4c82b8785d98cdd9fed4cac84d765d234ed3251bd6afe34cb7ac523cb93e8b4f", + "sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda", + "sha256:582530701bff1dec6779efa00c516496968edd851fba224fbd86e46cc6b73563", + "sha256:58455b79ec2661c3600e65c0a716955adc2410f7383755d537584b0de41b1d8a", + "sha256:58705da316756681ad3c9c73fd15499aa4d8c69f9fd38dc8a35e06c12468582f", + "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d", + "sha256:5c803c401ea1c1c18de70a06a6f79fcc9c5acfc79133e9869e730ad7f8ad8ef9", + "sha256:5cbabee4f083b6b4cd282f5b817a867cf0b1028c54d445b7ec7cfe6505057cf8", + "sha256:612dff5db80beef9e649c6d803a8d50c409082f1fedc9dbcdfde2983b2025b82", + "sha256:62c2caa1585c82b3f7a7ab56afef7b3602021d6da34fbc1cf234ff139fed3cd9", + "sha256:69606d7bb691b50a4240ce6b22ebb319c1cfb164e5f6569835058196e0f3a845", + "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82", + "sha256:6ed6ffac43aecfe6d86ec5b74b06a5be33d5bb9243d055141e8cabb12aa08125", + "sha256:703919b1633412ab54bcf920ab388735832fdcb9f9a00ae49387f0fe67dad504", + "sha256:766d8bbefcb9e00c3ac3b000d9acc51f1b399513f44d77dfe0eb026ad7c9a19b", + "sha256:80dd7db6a7cb57ffbc279c4394246414ec99537ae81ffd702443335a61dbf3a7", + "sha256:8112e52c5822fc4253f3901b676c55ddf288614dc7011634e2719718eaa187dc", + "sha256:8c8b293cd65ad716d13d8dd3624e42e5a19cc2a2f1acc74b30c2c13f15cb61a6", + "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40", + "sha256:91bd7d1773e64019f9288b7a5101f3ae50d3d8e6b1de7edee9c2ccc1d32f0c0a", + "sha256:95c658736ec15602da0ed73f312d410117723914a5c91a14ee4cdd72f1d790b3", + "sha256:99039fa9e6306880572915728d7f6c24a86ec57b0a83f6b2491e1d8ab0235b9a", + "sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72", + "sha256:9a7d15bbd2bc99e92e39f49a04653062ee6085c0e18b3b7512a4f2fe91f2d681", + "sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438", + "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae", + "sha256:9fee687dce376205d9a494e9c121e27183b2a3df18037f89d69bd7b35bcf59e2", + "sha256:a5aaeff38654462bc4b09023918b7f21790efb807f54c000a39d41d69cf552cb", + "sha256:a604bf7a053f8362d27eb9fefd2097f82600b856d5abe996d623babd067b1ab5", + "sha256:abbb9e76177c35d4e8568e58650aa6926040d6a9f6f03435b7a522bf1c487f9a", + "sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3", + "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8", + "sha256:b4e42a40a5e164cbfdb7b386c966a588b1047558a990981ace551ed7e12ca9c2", + "sha256:b5e251054542ae57ac7f3fba5d10bfff615b6c2fb09abeb37d2f1463f841ae22", + "sha256:b60fb58b90c6d63779cb0c0c54eeb38941bae3ecf7a73c764c52c88c2dcb9d72", + "sha256:b870b5df5b71d8c3359d21be8f0d6c485fa0ebdb6477dda51a1ea54a9b558061", + "sha256:ba0f0eb61ef00ea10e00eb53a9129501f52385c44853dbd6c4ad3f403603083f", + "sha256:bb87745b2e6dc56361bfde481d5a378dc314b252a98d7dd19a651a3fa58f24a9", + "sha256:bb90fb8bda722a1b9d48ac1e6c38f923ea757b3baf8ebd0c82e09c5c1a0e7a04", + "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98", + "sha256:c86563182421896d73858e08e1db93afdd2b947a70064b813d515d66549e15f9", + "sha256:c958bcfd59bacc2d0249dcfe575e71da54f9dcf4a8bdf89c4cb9a68a1170d73f", + "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b", + "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925", + "sha256:e3890b508a23299083e065f435a492b5435eba6e304a7114d2f919d400888cc6", + "sha256:e496a8ce2c256da1eb98bd15803a79bee00fc351f5dfb9ea82594a3f058309e0", + "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9", + "sha256:eaf675418ed6b3b31c7a989fd007fa7c3be66ce14e5c3b27336383604c9da85c", + "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991", + "sha256:ecc840861360ba9d176d413a5489b9a0aff6d6303d7e733e2c4623cfa26904a6", + "sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000", + "sha256:f393cda562f79828f38a819f4788641ac7c4085f30f1ce1a68672baa686482bb", + "sha256:f917c1180fdb8623c2b75a99192f4025e412597c50b2ac870f156de8fb101119", + "sha256:fc78a84e2dfbc27afe4b2bd7c80c8db9bca75cc5b85df52bfe634596a1da846b", + "sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58" + ], + "markers": "python_version >= '3.8'", + "version": "==1.17.2" }, "xmltodict": { "hashes": [ @@ -3036,11 +3066,11 @@ }, "faker": { "hashes": [ - "sha256:1c925fc0e86a51fc46648b504078c88d0cd48da1da2595c4e712841cab43a1e4", - "sha256:d30c5f0e2796b8970de68978365247657486eb0311c5abe88d0b895b68dff05d" + "sha256:49dde3b06a5602177bc2ad013149b6f60a290b7154539180d37b6f876ae79b20", + "sha256:ac4cf2f967ce02c898efa50651c43180bd658a7707cfd676fcc5410ad1482c03" ], "markers": "python_version >= '3.8'", - "version": "==33.1.0" + "version": "==33.3.1" }, "filelock": { "hashes": [ @@ -3232,11 +3262,11 @@ }, "identify": { "hashes": [ - "sha256:285a7d27e397652e8cafe537a6cc97dd470a970f48fb2e9d979aa38eae5513ac", - "sha256:993b0f01b97e0568c179bb9196391ff391bfb88a99099dbf5ce392b68f42d0af" + "sha256:14181a47091eb75b337af4c23078c9d09225cd4c48929f521f3bf16b09d02566", + "sha256:c10b33f250e5bba374fae86fb57f3adcebf1161bce7cdf92031915fd480c13bc" ], "markers": "python_version >= '3.9'", - "version": "==2.6.4" + "version": "==2.6.5" }, "idna": { "hashes": [ @@ -3246,14 +3276,6 @@ "markers": "python_version >= '3.6'", "version": "==3.10" }, - "importlib-metadata": { - "hashes": [ - "sha256:66f342cc6ac9818fc6ff340576acd24d65ba0b3efabb2b4ac08b598965a4a2f1", - "sha256:9a547d3bc3608b025f93d403fdd1aae741c24fbb8314df4b155675742ce303c5" - ], - "markers": "python_version >= '3.8'", - "version": "==8.4.0" - }, "iniconfig": { "hashes": [ "sha256:2d91e135bf72d31a410b17c16da610a82cb55f6b0477d1a902134b24a455b8b3", @@ -3668,11 +3690,11 @@ }, "pygments": { "hashes": [ - "sha256:786ff802f32e91311bff3889f6e9a86e81505fe99f2735bb6d60ae0c5004f199", - "sha256:b8e6aca0523f3ab76fee51799c488e38782ac06eafcf95e7ba832985c8e7b13a" + "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f", + "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c" ], "markers": "python_version >= '3.8'", - "version": "==2.18.0" + "version": "==2.19.1" }, "pyld": { "hashes": [ @@ -3709,12 +3731,12 @@ }, "pytest-asyncio": { "hashes": [ - "sha256:79be8a72384b0c917677e00daa711e07db15259f4d23203c59012bcd989d4aee", - "sha256:c84878849ec63ff2ca509423616e071ef9cd8cc93c053aa33b5b8fb70a990671" + "sha256:0d0bb693f7b99da304a0634afc0a4b19e49d5e0de2d670f38dc4bfa5727c5075", + "sha256:3f8ef9a98f45948ea91a0ed3dc4268b5326c0e7bce73892acc654df4262ad45f" ], "index": "pypi", "markers": "python_version >= '3.9'", - "version": "==0.25.1" + "version": "==0.25.2" }, "pytest-cov": { "hashes": [ @@ -3824,11 +3846,11 @@ "html" ], "hashes": [ - "sha256:164de86bd3564558802ca983d84f6616a4a1a420c7a17a8152f5016076b2913e", - "sha256:e590fa9a2c34ba33a667818b5a84be3fb8a4d85868f8038f17912ec84f912a25" + "sha256:4fc8f6d50b199dc38fbc5256370f038c1cedca6102ccbde4e37c0fd2b7f36e65", + "sha256:5a694a64f48a751079999c37dccf91a6210077d845d09adf7c3ce23a876265a7" ], - "markers": "python_full_version >= '3.8.1' and python_full_version < '4.0.0'", - "version": "==7.1.1" + "markers": "python_version >= '3.9' and python_version < '4'", + "version": "==7.1.2" }, "reproschema": { "hashes": [ @@ -3856,36 +3878,36 @@ }, "ruff": { "hashes": [ - "sha256:03a90200c5dfff49e4c967b405f27fdfa81594cbb7c5ff5609e42d7fe9680da5", - "sha256:1098d36f69831f7ff2a1da3e6407d5fbd6dfa2559e4f74ff2d260c5588900317", - "sha256:134ae019ef13e1b060ab7136e7828a6d83ea727ba123381307eb37c6bd5e01cb", - "sha256:4020d8bf8d3a32325c77af452a9976a9ad6455773bcb94991cf15bd66b347e47", - "sha256:587c5e95007612c26509f30acc506c874dab4c4abbacd0357400bd1aa799931b", - "sha256:5ad11a5e3868a73ca1fa4727fe7e33735ea78b416313f4368c504dbeb69c0f88", - "sha256:622b82bf3429ff0e346835ec213aec0a04d9730480cbffbb6ad9372014e31bbd", - "sha256:7512e8cb038db7f5db6aae0e24735ff9ea03bb0ed6ae2ce534e9baa23c1dc9ea", - "sha256:762f113232acd5b768d6b875d16aad6b00082add40ec91c927f0673a8ec4ede8", - "sha256:7b75ac29715ac60d554a049dbb0ef3b55259076181c3369d79466cb130eb5afd", - "sha256:8710ffd57bdaa6690cbf6ecff19884b8629ec2a2a2a2f783aa94b1cc795139ed", - "sha256:9d99cf80b0429cbebf31cbbf6f24f05a29706f0437c40413d950e67e2d4faca4", - "sha256:b5462d7804558ccff9c08fe8cbf6c14b7efe67404316696a2dde48297b1925bb", - "sha256:c01c048f9c3385e0fd7822ad0fd519afb282af9cf1778f3580e540629df89725", - "sha256:c9d526a62c9eda211b38463528768fd0ada25dad524cb33c0e99fcff1c67b5dc", - "sha256:d56de7220a35607f9fe59f8a6d018e14504f7b71d784d980835e20fc0611cd50", - "sha256:f69ab37771ea7e0715fead8624ec42996d101269a96e31f4d31be6fc33aa19b7", - "sha256:f99be814d77a5dac8a8957104bdd8c359e85c86b0ee0e38dca447cb1095f70fb" + "sha256:1a605fdcf6e8b2d39f9436d343d1f0ff70c365a1e681546de0104bef81ce88df", + "sha256:3292c5a22ea9a5f9a185e2d131dc7f98f8534a32fb6d2ee7b9944569239c648d", + "sha256:492a5e44ad9b22a0ea98cf72e40305cbdaf27fac0d927f8bc9e1df316dcc96eb", + "sha256:71cbe22e178c5da20e1514e1e01029c73dc09288a8028a5d3446e6bba87a5145", + "sha256:80605a039ba1454d002b32139e4970becf84b5fee3a3c3bf1c2af6f61a784347", + "sha256:82b35259b0cbf8daa22a498018e300b9bb0174c2bbb7bcba593935158a78054d", + "sha256:8b6a9701d1e371bf41dca22015c3f89769da7576884d2add7317ec1ec8cb9c3c", + "sha256:8efd9da7a1ee314b910da155ca7e8953094a7c10d0c0a39bfde3fcfd2a015684", + "sha256:9cc53e68b3c5ae41e8faf83a3b89f4a5d7b2cb666dff4b366bb86ed2a85b481f", + "sha256:a1b63fa24149918f8b37cef2ee6fff81f24f0d74b6f0bdc37bc3e1f2143e41c6", + "sha256:af1e9e9fe7b1f767264d26b1075ac4ad831c7db976911fa362d09b2d0356426a", + "sha256:b338edc4610142355ccf6b87bd356729b62bf1bc152a2fad5b0c7dc04af77bfe", + "sha256:b5eceb334d55fae5f316f783437392642ae18e16dcf4f1858d55d3c2a0f8f5d0", + "sha256:b9aab82bb20afd5f596527045c01e6ae25a718ff1784cb92947bff1f83068b00", + "sha256:c547f7f256aa366834829a08375c297fa63386cbe5f1459efaf174086b564247", + "sha256:c5e1d6abc798419cf46eed03f54f2e0c3adb1ad4b801119dedf23fcaf69b55b5", + "sha256:d18bba3d3353ed916e882521bc3e0af403949dbada344c20c16ea78f47af965e", + "sha256:fbd337bac1cfa96be615f6efcd4bc4d077edbc127ef30e2b8ba2a27e18c054d4" ], "index": "pypi", "markers": "python_version >= '3.7'", - "version": "==0.8.5" + "version": "==0.9.2" }, "setuptools": { "hashes": [ - "sha256:8199222558df7c86216af4f84c30e9b34a61d8ba19366cc914424cdbd28252f6", - "sha256:ce74b49e8f7110f9bf04883b730f4765b774ef3ef28f722cce7c273d253aaf7d" + "sha256:c5afc8f407c626b8313a86e10311dd3f661c6cd9c09d4bf8c15c0e11f9f2b0e6", + "sha256:e3982f444617239225d675215d51f6ba05f845d4eec313da4418fdbb56fb27e3" ], "markers": "python_version >= '3.9'", - "version": "==75.6.0" + "version": "==75.8.0" }, "six": { "hashes": [ @@ -3995,11 +4017,11 @@ }, "virtualenv": { "hashes": [ - "sha256:23eae1b4516ecd610481eda647f3a7c09aea295055337331bb4e6892ecce47b0", - "sha256:2c9c3262bb8e7b87ea801d715fae4495e6032450c71d2309be9550e7364049aa" + "sha256:4e4cb403c0b0da39e13b46b1b2476e505cb0046b25f242bee80f62bf990b2779", + "sha256:b8b8970138d32fb606192cb97f6cd4bb644fa486be9308fb9b63f81091b5dc35" ], "markers": "python_version >= '3.8'", - "version": "==20.28.0" + "version": "==20.29.1" }, "wcwidth": { "hashes": [ @@ -4008,14 +4030,6 @@ ], "version": "==0.2.13" }, - "zipp": { - "hashes": [ - "sha256:2c9958f6430a2040341a52eb608ed6dd93ef4392e02ffe219417c1b28b5dd1f4", - "sha256:ac1bbe05fd2991f160ebce24ffbac5f6d11d83dc90891255885223d42b3cd931" - ], - "markers": "python_version >= '3.9'", - "version": "==3.21.0" - }, "zope.event": { "hashes": [ "sha256:2832e95014f4db26c47a13fdaef84cef2f4df37e66b59d8f1f4a8f319a632c26", diff --git a/README.md b/README.md index 2096d053558..9d65a291601 100644 --- a/README.md +++ b/README.md @@ -38,7 +38,7 @@ See MindLogger's [Knowledge Base article](https://mindlogger.atlassian.net/servi ## Technologies -- ✅ [Python3.11+](https://www.python.org/downloads/release/python-31110/) +- ✅ [Python 3.13](https://www.python.org/downloads/release/python-3131/) - ✅ [Pipenv](https://pipenv.pypa.io/en/latest/) - ✅ [FastAPI](https://fastapi.tiangolo.com) - ✅ [Postgresql](https://www.postgresql.org/docs/14/index.html) @@ -61,7 +61,7 @@ And ### Prerequisites -- Python 3.11 +- Python 3.13 - [Docker](https://docs.docker.com/get-docker/) #### Recommended Extras @@ -71,7 +71,7 @@ Installing [pyenv](https://github.com/pyenv/pyenv) is recommended to automatical Alternatively, on macOS you can use a tool like [Homebrew](https://brew.sh/) to install multiple versions and specify when creating the virtual environment: ```bash -pipenv --python /opt/homebrew/bin/python3.11 +pipenv --python /opt/homebrew/bin/python3.13 ``` ### Environment Variables @@ -189,15 +189,15 @@ Create your virtual environment: pipenv shell ``` -If `pyenv` is installed Python 3.11 should automatically be installed in the virtual environment, you can check the +If `pyenv` is installed Python 3.13 should automatically be installed in the virtual environment, you can check the correct version of Python is active by running: ```bash python --version ``` -If the active version is **not** 3.11, you can manually specify a version while creating your virtual environment: +If the active version is **not** 3.13, you can manually specify a version while creating your virtual environment: ```bash -pipenv --python /opt/homebrew/bin/python3.11 +pipenv --python /opt/homebrew/bin/python3.13 ``` Install all dependencies diff --git a/compose/fastapi/Dockerfile b/compose/fastapi/Dockerfile index b6aaa539c0a..e6350a236da 100644 --- a/compose/fastapi/Dockerfile +++ b/compose/fastapi/Dockerfile @@ -1,4 +1,4 @@ -FROM python:3.11-slim-bookworm AS base +FROM python:3.13-slim-bookworm AS base ENV PYTHONUNBUFFERED=1 ENV PYTHONPATH="src/" diff --git a/conftest.py b/conftest.py index ef485f59048..9ad7d3b0e81 100644 --- a/conftest.py +++ b/conftest.py @@ -61,12 +61,12 @@ async def global_session(global_engine: AsyncEngine): # TODO: Instead of custom faketime for tests add function wrapper `now` -# to use it instead of builtin datetime.datetime.utcnow +# to use it instead of builtin datetime.datetime.now class FakeTime(datetime.datetime): current_utc = datetime.datetime(2024, 1, 1, 0, 0, 0) @classmethod - def utcnow(cls): + def now(cls, tzinfo=None): return cls.current_utc diff --git a/pyproject.toml b/pyproject.toml index d02572f6f95..ab49cff9f42 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -73,7 +73,7 @@ omit = [ [tool.mypy] plugins = ["pydantic.mypy"] ignore_missing_imports = true -python_version = '3.11' +python_version = '3.13' mypy_path = 'src' files = ['*.py'] warn_redundant_casts = true diff --git a/src/apps/activities/domain/constants_ab_trails_mobile.py b/src/apps/activities/domain/constants_ab_trails_mobile.py index 6052f2c5608..cc1a779e055 100644 --- a/src/apps/activities/domain/constants_ab_trails_mobile.py +++ b/src/apps/activities/domain/constants_ab_trails_mobile.py @@ -75,13 +75,12 @@ MOBILE_TUTORIALS_FIRST: ABTrailsTutorial = ABTrailsTutorial( tutorials=[ Tutorial(text="There are numbers in circles on this screen."), - Tutorial(text="You will take a pen and draw a line from one number " "to the next, in order."), + Tutorial(text="You will take a pen and draw a line from one number to the next, in order."), Tutorial(text="Start at 1.", node_label="1"), Tutorial(text="Then go to 2.", node_label="2"), Tutorial(text="Then 3, and so on.", node_label="3"), Tutorial( - text="Please try not to lift the pen as you move from one " - "number to the next. Work as quickly as you can." + text="Please try not to lift the pen as you move from one number to the next. Work as quickly as you can." ), Tutorial(text="Begin here.", node_label="1"), Tutorial(text="And end here.", node_label="11"), @@ -92,10 +91,10 @@ MOBILE_TUTORIALS_SECOND: ABTrailsTutorial = ABTrailsTutorial( tutorials=[ Tutorial(text="On this screen are more numbers in circles."), - Tutorial(text="You will take a pen and draw a line from one circle " "to the next, in order."), + Tutorial(text="You will take a pen and draw a line from one circle to the next, in order."), Tutorial(text="Start at 1.", node_label="1"), Tutorial(text="And End here.", node_label="11"), - Tutorial(text="Please try not to lift the pen as you move from one " "circle to the next."), + Tutorial(text="Please try not to lift the pen as you move from one circle to the next."), Tutorial(text="Work as quickly as you can."), Tutorial( text="Click next to start", @@ -106,14 +105,13 @@ MOBILE_TUTORIALS_THIRD: ABTrailsTutorial = ABTrailsTutorial( tutorials=[ Tutorial(text="There are numbers and letters in circles on this screen."), - Tutorial(text="You will take a pen and draw a line alternating in " "order between the numbers and letters."), + Tutorial(text="You will take a pen and draw a line alternating in order between the numbers and letters."), Tutorial(text="Start at number 1.", node_label="1"), Tutorial(text="Then go to the first letter A.", node_label="A"), Tutorial(text="Then go to the next number 2.", node_label="2"), Tutorial(text="Then go to the next letter B, and so on.", node_label="B"), Tutorial( - text="Please try not to lift the pen as you move from one " - "number to the next. Work as quickly as you can." + text="Please try not to lift the pen as you move from one number to the next. Work as quickly as you can." ), Tutorial(text="Begin here.", node_label="1"), Tutorial(text="And end here.", node_label="6"), @@ -125,12 +123,12 @@ MOBILE_TUTORIALS_FOURTH: ABTrailsTutorial = ABTrailsTutorial( tutorials=[ - Tutorial(text="On this screen there are more numbers and letters " "in circles."), - Tutorial(text="You will take a pen and draw a line from one circle " "to the next."), + Tutorial(text="On this screen there are more numbers and letters in circles."), + Tutorial(text="You will take a pen and draw a line from one circle to the next."), Tutorial(text="Alternating in order between the numbers and letters."), Tutorial(text="Start at 1.", node_label="1"), Tutorial(text="And end here.", node_label="6"), - Tutorial(text="Please try not to lift the pen as you move from one " "circle to the next."), + Tutorial(text="Please try not to lift the pen as you move from one circle to the next."), Tutorial(text="Work as quickly as you can."), Tutorial( text="Click next to start", diff --git a/src/apps/activities/domain/constants_ab_trails_tablet.py b/src/apps/activities/domain/constants_ab_trails_tablet.py index d2217ff8b5e..76467e42f22 100644 --- a/src/apps/activities/domain/constants_ab_trails_tablet.py +++ b/src/apps/activities/domain/constants_ab_trails_tablet.py @@ -109,13 +109,12 @@ TABLET_TUTORIALS_FIRST: ABTrailsTutorial = ABTrailsTutorial( tutorials=[ Tutorial(text="There are numbers in circles on this screen."), - Tutorial(text="You will take a pen and draw a line from one number " "to the next, in order."), + Tutorial(text="You will take a pen and draw a line from one number to the next, in order."), Tutorial(text="Start at 1.", node_label="1"), Tutorial(text="Then go to 2.", node_label="2"), Tutorial(text="Then 3, and so on.", node_label="3"), Tutorial( - text="Please try not to lift the pen as you move from one " - "number to the next. Work as quickly as you can." + text="Please try not to lift the pen as you move from one number to the next. Work as quickly as you can." ), Tutorial(text="Begin here.", node_label="1"), Tutorial(text="And end here.", node_label="8"), @@ -126,10 +125,10 @@ TABLET_TUTORIALS_SECOND: ABTrailsTutorial = ABTrailsTutorial( tutorials=[ Tutorial(text="On this screen are more numbers in circles."), - Tutorial(text="You will take a pen and draw a line from one circle to " "the next, in order."), + Tutorial(text="You will take a pen and draw a line from one circle to the next, in order."), Tutorial(text="Start at 1.", node_label="1"), Tutorial(text="And End here.", node_label="25"), - Tutorial(text="Please try not to lift the pen as you move from one " "circle to the next."), + Tutorial(text="Please try not to lift the pen as you move from one circle to the next."), Tutorial(text="Work as quickly as you can."), Tutorial( text="Click next to start", @@ -140,14 +139,13 @@ TABLET_TUTORIALS_THIRD: ABTrailsTutorial = ABTrailsTutorial( tutorials=[ Tutorial(text="There are numbers and letters in circles on this screen."), - Tutorial(text="You will take a pen and draw a line alternating in " "order between the numbers and letters."), + Tutorial(text="You will take a pen and draw a line alternating in order between the numbers and letters."), Tutorial(text="Start at number 1.", node_label="1"), Tutorial(text="Then go to the first letter A.", node_label="A"), Tutorial(text="Then go to the next number 2.", node_label="2"), Tutorial(text="Then go to the next letter B, and so on.", node_label="B"), Tutorial( - text="Please try not to lift the pen as you move from one " - "number to the next. Work as quickly as you can." + text="Please try not to lift the pen as you move from one number to the next. Work as quickly as you can." ), Tutorial(text="Begin here.", node_label="1"), Tutorial(text="And end here.", node_label="D"), @@ -159,12 +157,12 @@ TABLET_TUTORIALS_FOURTH: ABTrailsTutorial = ABTrailsTutorial( tutorials=[ - Tutorial(text="On this screen there are more numbers and letters " "in circles."), - Tutorial(text="You will take a pen and draw a line from one circle " "to the next."), + Tutorial(text="On this screen there are more numbers and letters in circles."), + Tutorial(text="You will take a pen and draw a line from one circle to the next."), Tutorial(text="Alternating in order between the numbers and letters."), Tutorial(text="Start at 1.", node_label="1"), Tutorial(text="And end here.", node_label="13"), - Tutorial(text="Please try not to lift the pen as you move from one " "circle to the next."), + Tutorial(text="Please try not to lift the pen as you move from one circle to the next."), Tutorial(text="Work as quickly as you can."), Tutorial( text="Click next to start", diff --git a/src/apps/activities/errors.py b/src/apps/activities/errors.py index a7a5b8d7484..f18b5a64fe5 100644 --- a/src/apps/activities/errors.py +++ b/src/apps/activities/errors.py @@ -94,7 +94,7 @@ class InvalidDataMatrixByOptionError(FieldError): class InvalidScoreLengthError(FieldError): - message = _("Scores must have the same length as the " "range of min_value and max_value") + message = _("Scores must have the same length as the range of min_value and max_value") class ActivityAccessDeniedError(AccessDeniedError): diff --git a/src/apps/activities/tests/test_activities.py b/src/apps/activities/tests/test_activities.py index f558c5bc066..198ead5bf73 100644 --- a/src/apps/activities/tests/test_activities.py +++ b/src/apps/activities/tests/test_activities.py @@ -636,7 +636,7 @@ async def test_activities_applet_has_score( en="Understand how was the morning", fr="Understand how was the morning", ), - items=[dict(activity_key="577dbbda-3afc-" "4962-842b-8d8d11588bfe")], + items=[dict(activity_key="577dbbda-3afc-4962-842b-8d8d11588bfe")], ) ], ) diff --git a/src/apps/activities/tests/unit/test_activity_change.py b/src/apps/activities/tests/unit/test_activity_change.py index db6b594870f..6330ecf0a0c 100644 --- a/src/apps/activities/tests/unit/test_activity_change.py +++ b/src/apps/activities/tests/unit/test_activity_change.py @@ -117,7 +117,7 @@ def old_activity(activity_history_id: uuid.UUID, old_applet_id: str, old_id_vers is_reviewable=False, response_is_editable=False, order=1, - created_at=datetime.datetime.utcnow(), + created_at=datetime.datetime.now(datetime.UTC), is_hidden=False, ) @@ -137,7 +137,7 @@ def new_activity(activity_history_id: uuid.UUID, new_applet_id: str, new_version is_reviewable=False, response_is_editable=False, order=1, - created_at=datetime.datetime.utcnow(), + created_at=datetime.datetime.now(datetime.UTC), is_hidden=False, ) diff --git a/src/apps/activities/tests/unit/test_activity_item_change.py b/src/apps/activities/tests/unit/test_activity_item_change.py index 64fd84ebba6..b08db0cd9f7 100644 --- a/src/apps/activities/tests/unit/test_activity_item_change.py +++ b/src/apps/activities/tests/unit/test_activity_item_change.py @@ -342,7 +342,7 @@ def test_conditional_logic_added(conditional_logic: ConditionalLogic): condition_type = condition.type.lower().replace("_", " ") item_name = condition.item_name value = condition.payload.value # type: ignore - assert changes == [f"{parent_name}: If All: " f"{item_name} {condition_type} {value} was added"] + assert changes == [f"{parent_name}: If All: {item_name} {condition_type} {value} was added"] def test_conditional_logic_changed(conditional_logic: ConditionalLogic): @@ -356,9 +356,7 @@ def test_conditional_logic_changed(conditional_logic: ConditionalLogic): condition_type = condition.type.lower().replace("_", " ") item_name = condition.item_name value = condition.payload.value # type: ignore - assert changes == [ - f"{parent_name}: If {new.match.capitalize()}: " f"{item_name} {condition_type} {value} was updated" - ] + assert changes == [f"{parent_name}: If {new.match.capitalize()}: {item_name} {condition_type} {value} was updated"] def test_conditional_logic_removed( diff --git a/src/apps/activity_assignments/crud/assignments.py b/src/apps/activity_assignments/crud/assignments.py index 1ee90e151c1..342fe7e3d12 100644 --- a/src/apps/activity_assignments/crud/assignments.py +++ b/src/apps/activity_assignments/crud/assignments.py @@ -288,7 +288,7 @@ async def upsert(self, values: dict) -> ActivityAssigmentSchema | None: else ActivityAssigmentSchema.activity_flow_id, ], set_={ - "updated_at": datetime.datetime.utcnow(), + "updated_at": datetime.datetime.now(datetime.UTC).replace(tzinfo=None), "is_deleted": False, }, where=(ActivityAssigmentSchema.soft_exists(exists=False)), diff --git a/src/apps/answers/router.py b/src/apps/answers/router.py index a123366e792..a5f45bf8ed3 100644 --- a/src/apps/answers/router.py +++ b/src/apps/answers/router.py @@ -330,7 +330,7 @@ )(answer_note_list) router.put( - "/applet/{applet_id}/answers/{answer_id}/activities/" "{activity_id}/notes/{note_id}", + "/applet/{applet_id}/answers/{answer_id}/activities/{activity_id}/notes/{note_id}", # noqa: E501 status_code=status.HTTP_200_OK, responses={ @@ -340,7 +340,7 @@ )(answer_note_edit) router.delete( - "/applet/{applet_id}/answers/{answer_id}/activities/" "{activity_id}/notes/{note_id}", + "/applet/{applet_id}/answers/{answer_id}/activities/{activity_id}/notes/{note_id}", # noqa: E501 status_code=status.HTTP_204_NO_CONTENT, responses={ diff --git a/src/apps/answers/service.py b/src/apps/answers/service.py index c468a624b11..9df048fbc43 100644 --- a/src/apps/answers/service.py +++ b/src/apps/answers/service.py @@ -308,7 +308,7 @@ async def _get_answer_relation( async def _create_answer(self, applet_answer: AppletAnswerCreate) -> AnswerSchema: assert self.user_id pk = self._generate_history_id(applet_answer.version) - created_at = applet_answer.created_at or datetime.datetime.utcnow() + created_at = applet_answer.created_at or datetime.datetime.now(datetime.UTC).replace(tzinfo=None) subject_crud = SubjectsCrud(self.session) respondent_subject = await subject_crud.get_user_subject( @@ -1036,21 +1036,21 @@ async def create_assessment_answer( AnswerItemSchema( id=assessment.id, created_at=assessment.created_at, - updated_at=datetime.datetime.utcnow(), + updated_at=datetime.datetime.now(datetime.UTC), answer_id=answer_id, respondent_id=self.user_id, answer=schema.answer, item_ids=list(map(str, schema.item_ids)), user_public_key=schema.reviewer_public_key, is_assessment=True, - start_datetime=datetime.datetime.utcnow(), - end_datetime=datetime.datetime.utcnow(), + start_datetime=datetime.datetime.now(datetime.UTC).replace(tzinfo=None), + end_datetime=datetime.datetime.now(datetime.UTC).replace(tzinfo=None), assessment_activity_id=schema.assessment_version_id, reviewed_flow_submit_id=submit_id, ) ) else: - now = datetime.datetime.utcnow() + now = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) await AnswerItemsCRUD(self.answer_session).create( AnswerItemSchema( answer_id=answer_id, @@ -2136,7 +2136,7 @@ async def create_report( data = dict( responses=responses, - now=datetime.datetime.utcnow().strftime("%x"), + now=datetime.datetime.now(datetime.UTC).strftime("%x"), user=user_info, applet=applet_full, ) @@ -2268,12 +2268,12 @@ async def decrypt_data_for_loris( ) as resp: duration = time.time() - start if resp.status == 200: - logger.info(f"Successful request (for LORIS) in {duration:.1f}" " seconds.") + logger.info(f"Successful request (for LORIS) in {duration:.1f} seconds.") response_data = await resp.json() # return ReportServerResponse(**response_data) return response_data, answer_versions else: - logger.error(f"Failed request (for LORIS) in {duration:.1f}" " seconds.") + logger.error(f"Failed request (for LORIS) in {duration:.1f} seconds.") error_message = await resp.text() raise ReportServerError(message=error_message) diff --git a/src/apps/answers/tests/conftest.py b/src/apps/answers/tests/conftest.py index 82f03c8687f..e511bbac1bb 100644 --- a/src/apps/answers/tests/conftest.py +++ b/src/apps/answers/tests/conftest.py @@ -215,9 +215,9 @@ def answer_item_create( identifier="encrypted_identifier", scheduled_time=None, scheduled_event_id=str(uuid.uuid4()), - start_time=datetime.datetime.utcnow(), - end_time=datetime.datetime.utcnow() + datetime.timedelta(seconds=1), - local_end_date=datetime.datetime.utcnow().date() - datetime.timedelta(days=1), + start_time=datetime.datetime.now(datetime.UTC), + end_time=datetime.datetime.now(datetime.UTC) + datetime.timedelta(seconds=1), + local_end_date=datetime.datetime.now(datetime.UTC).date() - datetime.timedelta(days=1), local_end_time=datetime.time(15, 0), user_public_key="public_key", ) @@ -235,7 +235,7 @@ def answer_create( submit_id=uuid.uuid4(), activity_id=applet.activities[0].id, answer=answer_item_create, - created_at=datetime.datetime.utcnow().replace(microsecond=0), + created_at=datetime.datetime.now(datetime.UTC).replace(microsecond=0), client=client_meta, consent_to_share=False, ) @@ -253,7 +253,7 @@ def answer_create_applet_one( submit_id=uuid.uuid4(), activity_id=applet_one.activities[0].id, answer=answer_item_create, - created_at=datetime.datetime.utcnow().replace(microsecond=0), + created_at=datetime.datetime.now(datetime.UTC).replace(microsecond=0), client=client_meta, ) @@ -276,7 +276,7 @@ def answer_with_alert_create( submit_id=uuid.uuid4(), activity_id=applet.activities[0].id, answer=answer_item_create, - created_at=datetime.datetime.utcnow().replace(microsecond=0), + created_at=datetime.datetime.now(datetime.UTC).replace(microsecond=0), client=client_meta, alerts=[answer_alert], consent_to_share=False, @@ -302,7 +302,7 @@ def public_answer_create( submit_id=uuid.uuid4(), activity_id=public_applet.activities[0].id, answer=item_create, - created_at=datetime.datetime.utcnow().replace(microsecond=0), + created_at=datetime.datetime.now(datetime.UTC).replace(microsecond=0), client=client_meta, consent_to_share=False, ) @@ -320,7 +320,7 @@ def answer_with_flow_create( submit_id=uuid.uuid4(), activity_id=applet.activities[0].id, answer=answer_item_create, - created_at=datetime.datetime.utcnow().replace(microsecond=0), + created_at=datetime.datetime.now(datetime.UTC).replace(microsecond=0), client=client_meta, flow_id=applet.activity_flows[0].id, is_flow_completed=True, @@ -353,7 +353,7 @@ def answer_reviewable_activity_create( submit_id=uuid.uuid4(), activity_id=activity.id, answer=item_create, - created_at=datetime.datetime.utcnow().replace(microsecond=0), + created_at=datetime.datetime.now(datetime.UTC).replace(microsecond=0), client=client_meta, consent_to_share=False, ) @@ -513,8 +513,8 @@ def tom_answer_create_data(tom, applet_with_reviewable_activity) -> AppletAnswer activity_id=applet_with_reviewable_activity.activities[0].id, answer=ItemAnswerCreate( item_ids=[applet_with_reviewable_activity.activities[0].items[0].id], - start_time=datetime.datetime.utcnow(), - end_time=datetime.datetime.utcnow(), + start_time=datetime.datetime.now(datetime.UTC), + end_time=datetime.datetime.now(datetime.UTC), user_public_key=str(tom.id), ), client=ClientMeta(app_id=f"{uuid.uuid4()}", app_version="1.1", width=984, height=623), @@ -593,7 +593,7 @@ def answers_reviewable_submission_create( submit_id=submit_id, activity_id=activity.id, answer=item_create, - created_at=datetime.datetime.utcnow().replace(microsecond=0), + created_at=datetime.datetime.now(datetime.UTC).replace(microsecond=0), client=client_meta, flow_id=applet_with_reviewable_flow.activity_flows[0].id, ) diff --git a/src/apps/answers/tests/test_answers.py b/src/apps/answers/tests/test_answers.py index 9aaf629d2a3..574ba3ee05c 100644 --- a/src/apps/answers/tests/test_answers.py +++ b/src/apps/answers/tests/test_answers.py @@ -184,8 +184,8 @@ async def tom_answer_item_for_applet(tom: User, applet: AppletFull, session: Asy respondent_id=tom.id, answer=uuid.uuid4().hex, item_ids=[str(item.id) for item in applet.activities[0].items], - start_datetime=datetime.datetime.utcnow(), - end_datetime=datetime.datetime.utcnow(), + start_datetime=datetime.datetime.now(datetime.UTC).replace(tzinfo=None), + end_datetime=datetime.datetime.now(datetime.UTC).replace(tzinfo=None), is_assessment=False, ) @@ -211,8 +211,8 @@ async def answer_shell_account_target(tom: User, applet: AppletFull, session: As activity_id=applet.activities[0].id, answer=ItemAnswerCreate( item_ids=[applet.activities[0].items[0].id], - start_time=datetime.datetime.utcnow(), - end_time=datetime.datetime.utcnow(), + start_time=datetime.datetime.now(datetime.UTC), + end_time=datetime.datetime.now(datetime.UTC), user_public_key=str(tom.id), ), client=ClientMeta(app_id=f"{uuid.uuid4()}", app_version="1.1", width=984, height=623), @@ -238,8 +238,8 @@ async def answer_shell_account_target(tom: User, applet: AppletFull, session: As source_subject_tag="Child", source_nickname=shell_account.nickname, source_secret_user_id=shell_account.secret_user_id, - start_datetime=datetime.datetime.utcnow(), - end_datetime=datetime.datetime.utcnow(), + start_datetime=datetime.datetime.now(datetime.UTC), + end_datetime=datetime.datetime.now(datetime.UTC), ) @@ -256,8 +256,8 @@ async def tom_answer_on_reviewable_applet( activity_id=applet_with_reviewable_activity.activities[0].id, answer=ItemAnswerCreate( item_ids=[applet_with_reviewable_activity.activities[0].items[0].id], - start_time=datetime.datetime.utcnow(), - end_time=datetime.datetime.utcnow(), + start_time=datetime.datetime.now(datetime.UTC), + end_time=datetime.datetime.now(datetime.UTC), user_public_key=str(tom.id), ), client=ClientMeta(app_id=f"{uuid.uuid4()}", app_version="1.1", width=984, height=623), @@ -277,8 +277,8 @@ async def lucy_answer(session: AsyncSession, lucy: User, applet: AppletFull) -> activity_id=applet.activities[0].id, answer=ItemAnswerCreate( item_ids=[applet.activities[0].items[0].id], - start_time=datetime.datetime.utcnow(), - end_time=datetime.datetime.utcnow(), + start_time=datetime.datetime.now(datetime.UTC), + end_time=datetime.datetime.now(datetime.UTC), user_public_key=str(lucy.id), ), client=ClientMeta(app_id=f"{uuid.uuid4()}", app_version="1.1", width=984, height=623), @@ -299,8 +299,8 @@ async def tom_answer_activity_flow(session: AsyncSession, tom: User, applet_with activity_id=applet_with_flow.activities[0].id, answer=ItemAnswerCreate( item_ids=[applet_with_flow.activities[0].items[0].id], - start_time=datetime.datetime.utcnow(), - end_time=datetime.datetime.utcnow(), + start_time=datetime.datetime.now(datetime.UTC), + end_time=datetime.datetime.now(datetime.UTC), user_public_key=str(tom.id), identifier="encrypted_identifier", ), @@ -325,8 +325,8 @@ async def tom_answer_activity_flow_incomplete( activity_id=applet_with_flow.activities[0].id, answer=ItemAnswerCreate( item_ids=[applet_with_flow.activities[0].items[0].id], - start_time=datetime.datetime.utcnow(), - end_time=datetime.datetime.utcnow(), + start_time=datetime.datetime.now(datetime.UTC), + end_time=datetime.datetime.now(datetime.UTC), user_public_key=str(tom.id), identifier="encrypted_identifier", ), @@ -344,8 +344,8 @@ def applet_with_flow_answer_create(applet_with_flow: AppletFull) -> list[AppletA client=ClientMeta(app_id=f"{uuid.uuid4()}", app_version="1.1", width=984, height=623), ) answer_item_data = dict( - start_time=datetime.datetime.utcnow(), - end_time=datetime.datetime.utcnow(), + start_time=datetime.datetime.now(datetime.UTC), + end_time=datetime.datetime.now(datetime.UTC), user_public_key=str(uuid.uuid4()), ) answers = [ @@ -429,8 +429,8 @@ async def tom_answer_activity_no_flow(session: AsyncSession, tom: User, applet_w activity_id=applet_with_flow.activities[0].id, answer=ItemAnswerCreate( item_ids=[applet_with_flow.activities[0].items[0].id], - start_time=datetime.datetime.utcnow(), - end_time=datetime.datetime.utcnow(), + start_time=datetime.datetime.now(datetime.UTC), + end_time=datetime.datetime.now(datetime.UTC), user_public_key=str(tom.id), ), client=ClientMeta(app_id=f"{uuid.uuid4()}", app_version="1.1", width=984, height=623), @@ -566,8 +566,8 @@ async def tom_answer_activity_flow_not_completed( activity_id=applet_with_flow.activities[0].id, answer=ItemAnswerCreate( item_ids=[applet_with_flow.activities[0].items[0].id], - start_time=datetime.datetime.utcnow(), - end_time=datetime.datetime.utcnow(), + start_time=datetime.datetime.now(datetime.UTC), + end_time=datetime.datetime.now(datetime.UTC), user_public_key=str(tom.id), identifier="encrypted_identifier", ), @@ -594,8 +594,8 @@ async def applet__with_deleted_activities_and_answers( activity_id=activity.id, answer=ItemAnswerCreate( item_ids=[activity.items[0].id], - start_time=datetime.datetime.utcnow(), - end_time=datetime.datetime.utcnow(), + start_time=datetime.datetime.now(datetime.UTC), + end_time=datetime.datetime.now(datetime.UTC), user_public_key=str(tom.id), identifier="encrypted_identifier", ), @@ -627,8 +627,8 @@ async def applet__with_deleted_and_order( is_flow_completed=True, answer=ItemAnswerCreate( item_ids=[activity.items[0].id], - start_time=datetime.datetime.utcnow(), - end_time=datetime.datetime.utcnow(), + start_time=datetime.datetime.now(datetime.UTC), + end_time=datetime.datetime.now(datetime.UTC), user_public_key=str(tom.id), identifier="encrypted_identifier", ), @@ -763,7 +763,7 @@ async def test_answer_activity_answer_dates_for_respondent( self.review_activities_url.format(applet_id=str(answer_with_alert_create.applet_id)), dict( targetSubjectId=tom_applet_subject.id, - createdDate=datetime.datetime.utcnow().date(), + createdDate=datetime.datetime.now(datetime.UTC).date(), ), ) assert response.status_code == http.HTTPStatus.OK, response.json() @@ -1518,7 +1518,7 @@ async def test_answered_applet_activities_1( self.review_activities_url.format(applet_id=str(tom_answer.applet_id)), dict( targetSubjectId=tom_applet_subject.id, - createdDate=datetime.datetime.utcnow().date(), + createdDate=datetime.datetime.now(datetime.UTC).date(), ), ) @@ -1697,7 +1697,7 @@ async def test_applet_assessment_create( ) ) assert response.status_code == http.HTTPStatus.OK - assessment = response.json()["result"] + assessment: dict = response.json()["result"] assert assessment["answer"] == assessment_create.answer assert assessment["reviewerPublicKey"] == assessment_create.reviewer_public_key assert assessment["itemIds"] == [str(i) for i in assessment_create.item_ids] @@ -1749,7 +1749,7 @@ async def test_applet_activities(self, client: TestClient, tom: User, answer: An self.review_activities_url.format(applet_id=str(answer.applet_id)), dict( targetSubjectId=tom_applet_subject.id, - createdDate=datetime.datetime.utcnow().date(), + createdDate=datetime.datetime.now(datetime.UTC).date(), ), ) @@ -1928,7 +1928,7 @@ async def test_get_activity_identifiers( assert response.status_code == http.HTTPStatus.OK assert response.json()["count"] == 0 - created_at = datetime.datetime.utcnow() + created_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) data = answer_create.copy(deep=True) data.created_at = created_at @@ -2236,7 +2236,7 @@ async def test_check_existence_answer_exists(self, client: TestClient, tom: User "column,value", ( ("activity_id", "00000000-0000-0000-0000-000000000000_99"), - ("created_at", datetime.datetime.utcnow().timestamp() * 1000), + ("created_at", datetime.datetime.now(datetime.UTC).timestamp() * 1000), ), ) async def test_check_existence_answer_does_not_exist( @@ -2415,8 +2415,8 @@ async def test_summary_activities_submitted_date_with_answers( activity_id=applet_with_reviewable_activity.activities[0].id, answer=ItemAnswerCreate( item_ids=[applet_with_reviewable_activity.activities[0].items[0].id], - start_time=datetime.datetime.utcnow(), - end_time=datetime.datetime.utcnow(), + start_time=datetime.datetime.now(datetime.UTC), + end_time=datetime.datetime.now(datetime.UTC), user_public_key=str(tom.id), ), client=ClientMeta(app_id=f"{uuid.uuid4()}", app_version="1.1", width=984, height=623), @@ -2577,7 +2577,7 @@ async def test_review_flows_one_answer( url, dict( targetSubjectId=tom_subject.id, - createdDate=datetime.datetime.utcnow().date(), + createdDate=datetime.datetime.now(datetime.UTC).date(), ), ) assert response.status_code == 200 @@ -2612,7 +2612,7 @@ async def test_review_flows_one_answer_incomplete_submission( url, dict( targetSubjectId=tom_subject.id, - createdDate=datetime.datetime.utcnow().date(), + createdDate=datetime.datetime.now(datetime.UTC).date(), ), ) assert response.status_code == 200 @@ -2644,7 +2644,7 @@ async def test_review_flows_multiple_answers( url, dict( targetSubjectId=tom_subject.id, - createdDate=datetime.datetime.utcnow().date(), + createdDate=datetime.datetime.now(datetime.UTC).date(), ), ) assert response.status_code == 200 @@ -3045,7 +3045,7 @@ async def test_review_flows_one_answer_without_target_subject_id( response = await client.get( url, dict( - createdDate=datetime.datetime.utcnow().date(), + createdDate=datetime.datetime.now(datetime.UTC).date(), ), ) assert response.status_code == 422 diff --git a/src/apps/answers/tests/test_answers_arbitrary.py b/src/apps/answers/tests/test_answers_arbitrary.py index 623aa6b4e7e..7527ec1e5ee 100644 --- a/src/apps/answers/tests/test_answers_arbitrary.py +++ b/src/apps/answers/tests/test_answers_arbitrary.py @@ -171,7 +171,7 @@ async def test_answer_activity_items_create_for_respondent( self.review_activities_url.format(applet_id=str(answer_with_alert_create.applet_id)), dict( targetSubjectId=subject.id, - createdDate=datetime.datetime.utcnow().date(), + createdDate=datetime.datetime.now(datetime.UTC).date(), ), ) @@ -347,7 +347,7 @@ async def test_answered_applet_activities( self.review_activities_url.format(applet_id=str(answer_create.applet_id)), dict( targetSubjectId=tom_subject.id, - createdDate=datetime.datetime.utcnow().date(), + createdDate=datetime.datetime.now(datetime.UTC).date(), ), ) @@ -372,7 +372,7 @@ async def test_answered_applet_activities( self.review_activities_url.format(applet_id=str(answer_create.applet_id)), dict( targetSubjectId=tom_subject.id, - createdDate=datetime.datetime.utcnow().date(), + createdDate=datetime.datetime.now(datetime.UTC).date(), ), ) @@ -467,7 +467,7 @@ async def test_applet_assessment_create( ) ) assert response.status_code == http.HTTPStatus.OK - assessment = response.json()["result"] + assessment: dict = response.json()["result"] assert assessment["answer"] == assessment_arbitrary_create.answer assert assessment["reviewerPublicKey"] == assessment_arbitrary_create.reviewer_public_key assert assessment["itemIds"] == [str(i) for i in assessment_arbitrary_create.item_ids] @@ -512,7 +512,7 @@ async def test_applet_activities( self.review_activities_url.format(applet_id=str(answer_arbitrary.applet_id)), dict( targetSubjectId=tom_applet_subject.id, - createdDate=datetime.datetime.utcnow().date(), + createdDate=datetime.datetime.now(datetime.UTC).date(), ), ) @@ -665,7 +665,7 @@ async def test_get_identifiers( assert response.status_code == http.HTTPStatus.OK assert response.json()["count"] == 0 - created_at = datetime.datetime.utcnow() + created_at = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) data = answer_create.copy(deep=True) data.created_at = created_at @@ -852,7 +852,7 @@ async def test_check_existance_answer_exists( "column,value", ( ("activity_id", "00000000-0000-0000-0000-000000000000_99"), - ("created_at", datetime.datetime.utcnow().timestamp() * 1000), + ("created_at", datetime.datetime.now(datetime.UTC).timestamp() * 1000), ), ) async def test_check_existance_answer_does_not_exist( @@ -863,8 +863,8 @@ async def test_check_existance_answer_does_not_exist( "applet_id": str(answer_arbitrary.applet_id), "activity_id": answer_arbitrary.activity_history_id.split("_")[0], "created_at": answer_arbitrary.created_at.timestamp(), + column: value, } - data[column] = value resp = await arbitrary_client.post(self.check_existence_url, data=data) assert resp.status_code == http.HTTPStatus.OK assert not resp.json()["result"]["exists"] diff --git a/src/apps/applets/commands/applet_ema.py b/src/apps/applets/commands/applet_ema.py index 0595abcb7f6..f14072bf799 100644 --- a/src/apps/applets/commands/applet_ema.py +++ b/src/apps/applets/commands/applet_ema.py @@ -128,7 +128,7 @@ class ActivityEventRawRow(RawRow): def is_last_day_of_month(date: datetime.date): mdays = calendar.mdays.copy() # type: ignore[attr-defined] if calendar.isleap(date.year): - mdays[calendar.February] += 1 # type: ignore[attr-defined] + mdays[calendar.FEBRUARY] += 1 return date.day == mdays[date.month] @@ -210,7 +210,7 @@ async def _export_flows(applet_id: uuid.UUID, path_prefix: str): @app.command( short_help=f'Export applet "{APPLET_NAME or "NOT CONFIGURED"}"({APPLET_ID or "NOT CONFIGURED"})' - f' flow data as csv file' + f" flow data as csv file" ) @coro async def export_flows( diff --git a/src/apps/authentication/crud.py b/src/apps/authentication/crud.py index 9ccd8115f47..33058e77b30 100644 --- a/src/apps/authentication/crud.py +++ b/src/apps/authentication/crud.py @@ -13,7 +13,7 @@ async def create(self, token: InternalToken, type_: TokenPurpose): TokenBlacklistSchema( jti=token.payload.jti, user_id=token.payload.sub, - exp=datetime.datetime.utcfromtimestamp(token.payload.exp), + exp=datetime.datetime.fromtimestamp(token.payload.exp, datetime.UTC).replace(tzinfo=None), type=type_, rjti=token.payload.rjti, ) diff --git a/src/apps/authentication/deps.py b/src/apps/authentication/deps.py index 717aa9cf597..c5d7f8b4f29 100644 --- a/src/apps/authentication/deps.py +++ b/src/apps/authentication/deps.py @@ -1,4 +1,4 @@ -from datetime import datetime +from datetime import datetime, timezone import jwt from fastapi import Depends, HTTPException, status @@ -44,7 +44,7 @@ async def get_current_user_for_ws(websocket: WebSocket, session=Depends(get_sess ) token_data = TokenPayload(**payload) - if datetime.utcfromtimestamp(token_data.exp) < datetime.utcnow(): + if datetime.fromtimestamp(token_data.exp, timezone.utc) < datetime.now(timezone.utc): raise AuthenticationError except (jwt.PyJWTError, ValidationError): raise AuthenticationError @@ -75,7 +75,7 @@ async def _get_current_token( token_payload = TokenPayload(**payload) - if datetime.utcfromtimestamp(token_payload.exp) < datetime.utcnow(): + if datetime.fromtimestamp(token_payload.exp, timezone.utc) < datetime.now(timezone.utc): raise AuthenticationError except (jwt.PyJWTError, ValidationError): raise AuthenticationError diff --git a/src/apps/authentication/services/core.py b/src/apps/authentication/services/core.py index 952100bdaff..b4c2f5f929c 100644 --- a/src/apps/authentication/services/core.py +++ b/src/apps/authentication/services/core.py @@ -14,8 +14,8 @@ async def is_revoked(self, token: InternalToken) -> bool: return await TokenBlacklistCRUD(self.session).exists(token) async def revoke(self, token: InternalToken, type_: TokenPurpose) -> None: - now = datetime.datetime.utcnow() - ttl = token.payload.exp - int(now.replace(tzinfo=datetime.timezone.utc).timestamp()) + now = datetime.datetime.now(datetime.UTC) + ttl = token.payload.exp - int(now.timestamp()) if ttl > 1: revoked = await self.is_revoked(token) if not revoked: diff --git a/src/apps/authentication/services/security.py b/src/apps/authentication/services/security.py index cdf3416b379..d6eb1162771 100644 --- a/src/apps/authentication/services/security.py +++ b/src/apps/authentication/services/security.py @@ -23,7 +23,7 @@ def __init__(self, session) -> None: def create_access_token(data: dict) -> str: to_encode = data.copy() expires_delta = timedelta(minutes=settings.authentication.access_token.expiration) - expire = datetime.utcnow() + expires_delta + expire = datetime.now(timezone.utc) + expires_delta to_encode.setdefault(JWTClaim.exp, expire) to_encode.setdefault(JWTClaim.jti, str(uuid.uuid4())) encoded_jwt = jwt.encode( @@ -37,7 +37,7 @@ def create_access_token(data: dict) -> str: def create_refresh_token(data: dict) -> str: to_encode = data.copy() expires_delta = timedelta(minutes=settings.authentication.refresh_token.expiration) - expire = datetime.utcnow() + expires_delta + expire = datetime.now(timezone.utc) + expires_delta to_encode.setdefault(JWTClaim.exp, expire) to_encode.setdefault(JWTClaim.jti, str(uuid.uuid4())) encoded_jwt = jwt.encode( @@ -68,14 +68,14 @@ def _get_refresh_token_by_access(self, token: InternalToken) -> InternalToken | if not token.payload.rjti: return None - access_exp = datetime.utcfromtimestamp(token.payload.exp) + access_exp = datetime.fromtimestamp(token.payload.exp, timezone.utc) refresh_expires_delta = timedelta(minutes=settings.authentication.refresh_token.expiration) access_expires_delta = timedelta(minutes=settings.authentication.access_token.expiration) expire = access_exp - access_expires_delta + refresh_expires_delta refresh_token = InternalToken( payload=TokenPayload( sub=token.payload.sub, - exp=expire.replace(tzinfo=timezone.utc).timestamp(), + exp=int(expire.timestamp()), jti=token.payload.rjti, ) ) diff --git a/src/apps/file/services.py b/src/apps/file/services.py index b175aa00d3d..e758480a5b4 100644 --- a/src/apps/file/services.py +++ b/src/apps/file/services.py @@ -212,7 +212,7 @@ def raise_for_access(email: str): @staticmethod def need_to_rotate(first_file_name: str) -> bool: - now_ts = datetime.datetime.utcnow() + now_ts = datetime.datetime.now(datetime.UTC) file_ts_part = first_file_name.split()[-1:] if not file_ts_part: return False diff --git a/src/apps/folders/crud.py b/src/apps/folders/crud.py index 0892c61e0e7..2f2febfd549 100644 --- a/src/apps/folders/crud.py +++ b/src/apps/folders/crud.py @@ -102,7 +102,7 @@ async def pin_applet(self, folder_id: uuid.UUID, applet_id: uuid.UUID): query: Query = update(FolderAppletSchema) query = query.where(FolderAppletSchema.folder_id == folder_id) query = query.where(FolderAppletSchema.applet_id == applet_id) - query = query.values(pinned_at=datetime.datetime.utcnow()) + query = query.values(pinned_at=datetime.datetime.now(datetime.UTC).replace(tzinfo=None)) await self._execute(query) diff --git a/src/apps/integrations/loris/service/loris.py b/src/apps/integrations/loris/service/loris.py index e8829757b02..4f021088c61 100644 --- a/src/apps/integrations/loris/service/loris.py +++ b/src/apps/integrations/loris/service/loris.py @@ -197,7 +197,7 @@ async def integration(self, users_and_visits) -> None: headers, candidate_id, filtered_answers, activities_ids, users_and_visits[user] ) - logger.info(f"Successfully send data for user: {user}," f" with loris id: {candidate_id}") + logger.info(f"Successfully send data for user: {user}, with loris id: {candidate_id}") await self._create_integration_alerts(self.applet_id, message=LorisIntegrationAlertMessages.SUCCESS.value) logger.info("All finished") @@ -644,7 +644,7 @@ async def _add_instrument_to_loris( else: logger.info(f"Failed request in {duration:.1f} seconds.") error_message = await resp.text() - logger.info(f"response is: " f"{error_message}\nstatus is: {resp.status}") + logger.info(f"response is: {error_message}\nstatus is: {resp.status}") await self._create_integration_alerts( self.applet_id, message=LorisIntegrationAlertMessages.LORIS_SERVER_ERROR.value ) @@ -696,7 +696,7 @@ async def _add_instrument_data_to_loris( else: logger.info(f"Failed request in {duration:.1f} seconds.") error_message = await resp.text() - logger.info(f"response is: " f"{error_message}\nstatus is: {resp.status}") + logger.info(f"response is: {error_message}\nstatus is: {resp.status}") await self._create_integration_alerts( self.applet_id, message=LorisIntegrationAlertMessages.LORIS_SERVER_ERROR.value ) diff --git a/src/apps/invitations/domain.py b/src/apps/invitations/domain.py index 17ffab9d7e4..24b092c19f9 100644 --- a/src/apps/invitations/domain.py +++ b/src/apps/invitations/domain.py @@ -305,13 +305,13 @@ class _InvitationResponse(PublicModel): description="This field represents the specific invitation id", ) applet_id: uuid.UUID = Field( - description="This field represents the specific applet id " "for invitation", + description="This field represents the specific applet id for invitation", ) applet_name: str = Field( - description="This field represents the specific applet name " "for invitation", + description="This field represents the specific applet name for invitation", ) key: uuid.UUID = Field( - description="This field represents the universally unique " "identifiers for invitation", + description="This field represents the universally unique identifiers for invitation", ) status: InvitationStatus = Field( description="This field represents the status for invitation", @@ -324,7 +324,7 @@ class _InvitationResponse(PublicModel): ) user_id: uuid.UUID | None = Field( None, - description="This field respresents registered user or not. " "Used for tests", + description="This field respresents registered user or not. Used for tests", ) tag: str | None = Field(None, description="This field represents subject tag") diff --git a/src/apps/invitations/test_invite.py b/src/apps/invitations/test_invite.py index 3a36de67c95..c175ddc692e 100644 --- a/src/apps/invitations/test_invite.py +++ b/src/apps/invitations/test_invite.py @@ -816,7 +816,7 @@ async def test_send_incorrect_role_to_invite_managers( data, ) assert resp.status_code == http.HTTPStatus.UNPROCESSABLE_ENTITY - emsg = "value is not a valid enumeration member; " "permitted: 'manager', 'coordinator', 'editor'" + emsg = "value is not a valid enumeration member; permitted: 'manager', 'coordinator', 'editor'" result = resp.json()["result"] assert len(result) == 1 assert result[0]["message"] == emsg diff --git a/src/apps/jsonld_converter/service/document/base.py b/src/apps/jsonld_converter/service/document/base.py index 38a05b581ad..ac928f00e7f 100644 --- a/src/apps/jsonld_converter/service/document/base.py +++ b/src/apps/jsonld_converter/service/document/base.py @@ -236,7 +236,7 @@ def _get_ld_properties_formatted(self, doc: dict, drop=False, key="reproschema:a def _get_allow_list(self, doc: dict, drop=False) -> list[str]: rules = self.attr_processor.get_attr_list(doc, "reproschema:allow", drop=drop) or [] - return [rule.get(LdKeyword.id) if isinstance(rule, dict) else rule for rule in rules] + return [rule.get(LdKeyword.id) if isinstance(rule, dict) else rule for rule in rules] # type: ignore def _is_allowed(self, allow_list: list[str], keys: list[str]) -> bool: for key in keys: diff --git a/src/apps/jsonld_converter/service/document/report.py b/src/apps/jsonld_converter/service/document/report.py index 83d264642db..b436cb25858 100644 --- a/src/apps/jsonld_converter/service/document/report.py +++ b/src/apps/jsonld_converter/service/document/report.py @@ -151,6 +151,7 @@ def _get_score_items(cls, expression: str | None) -> list[str]: @property def calculation_type(self) -> CalculationType: + assert self.ld_output_type if self.ld_output_type == "cumulative": return CalculationType.SUM return CalculationType(self.ld_output_type) diff --git a/src/apps/jsonld_converter/service/export/activity_item.py b/src/apps/jsonld_converter/service/export/activity_item.py index a8d42b21294..7af9aab4fe5 100644 --- a/src/apps/jsonld_converter/service/export/activity_item.py +++ b/src/apps/jsonld_converter/service/export/activity_item.py @@ -204,7 +204,7 @@ def _build_choices_prop(self, values: SliderValues) -> list: "schema:value": v, } if scores: - choice["schema:score"] = scores[i] + choice["schema:score"] = scores[i] # type: ignore[assignment] if image: choice["schema:image"] = image @@ -272,7 +272,7 @@ def _build_response_options_prop(self, model: ActivityItemFull) -> dict: "schema:maxValue": row.max_label, "schema:minValueImg": row.min_image, "schema:maxValueImg": row.max_image, - "choices": self._build_choices_prop(row), + "choices": self._build_choices_prop(row), # type: ignore[arg-type] } slider_options.append(option) diff --git a/src/apps/jsonld_converter/service/export/conditional_logic.py b/src/apps/jsonld_converter/service/export/conditional_logic.py index 15a169b450b..6c687687ecc 100644 --- a/src/apps/jsonld_converter/service/export/conditional_logic.py +++ b/src/apps/jsonld_converter/service/export/conditional_logic.py @@ -64,7 +64,7 @@ def export(self) -> str: operator = self.simple_operator_map.get(type_) # type: ignore[call-overload] # noqa: E501 if isinstance(payload, OptionPayload): try: - val: int | str = int(payload.option_value) # TODO actualize on PR merge + val: int | str | float = int(payload.option_value) # TODO actualize on PR merge except ValueError: val = f'"{payload.option_value}"' # TODO actualize on PR merge elif isinstance(payload, ValuePayload): diff --git a/src/apps/schedule/commands/remove_events.py b/src/apps/schedule/commands/remove_events.py index 2a6a3300bb5..090acb357d6 100644 --- a/src/apps/schedule/commands/remove_events.py +++ b/src/apps/schedule/commands/remove_events.py @@ -28,7 +28,7 @@ async def remove_events(): assessments = await get_assessments(session) service = ScheduleService(session) for activity in assessments: - print(f"Applet: {activity.applet_id} " f"Activity: {activity.id}") + print(f"Applet: {activity.applet_id} Activity: {activity.id}") await service.delete_by_activity_ids(activity.applet_id, [activity.id]) except Exception as ex: print(ex) diff --git a/src/apps/schedule/domain/schedule/base.py b/src/apps/schedule/domain/schedule/base.py index 009ec00a325..6025c2c6e08 100644 --- a/src/apps/schedule/domain/schedule/base.py +++ b/src/apps/schedule/domain/schedule/base.py @@ -19,7 +19,7 @@ class BasePeriodicity(BaseModel): end_date: date | None selected_date: date | None = Field( None, - description="If type is WEEKLY, MONTHLY or ONCE," " selectedDate must be set.", + description="If type is WEEKLY, MONTHLY or ONCE, selectedDate must be set.", ) @root_validator diff --git a/src/apps/schedule/errors.py b/src/apps/schedule/errors.py index 725dd6826f6..21e8cbbe20d 100644 --- a/src/apps/schedule/errors.py +++ b/src/apps/schedule/errors.py @@ -74,7 +74,7 @@ class OneTimeCompletionCaseError(FieldError): class StartEndTimeAccessBeforeScheduleCaseError(FieldError): - message = _("start_time, end_time, access_before_schedule " "must be set if periodicity is not ALWAYS.") + message = _("start_time, end_time, access_before_schedule must be set if periodicity is not ALWAYS.") class StartEndTimeEqualError(FieldError): diff --git a/src/apps/shared/commands/encryption.py b/src/apps/shared/commands/encryption.py index 0ee7cbc86b1..c33e5ce6f9f 100644 --- a/src/apps/shared/commands/encryption.py +++ b/src/apps/shared/commands/encryption.py @@ -112,7 +112,7 @@ async def reencrypt( print(f"Started reencrypting data in the table {table_name}") columns = table_name_column_name_map.get(table_name, []) if not columns: - print("[red]" f"[bold]{table_name}[/bold] table does not have encrypted columns. Skipped[red]") + print(f"[red][bold]{table_name}[/bold] table does not have encrypted columns. Skipped[red]") continue for column in columns: print(f"Update column {column}") diff --git a/src/apps/shared/commands/patches/m2_4611_add_answer_subjects.py b/src/apps/shared/commands/patches/m2_4611_add_answer_subjects.py index ec33cc8e685..c797a745e28 100644 --- a/src/apps/shared/commands/patches/m2_4611_add_answer_subjects.py +++ b/src/apps/shared/commands/patches/m2_4611_add_answer_subjects.py @@ -46,7 +46,7 @@ async def main( try: await update_answers(arb_session) await arb_session.commit() - print(f"Processing workspace#{i + 1} {workspace.id} " f"finished") + print(f"Processing workspace#{i + 1} {workspace.id} finished") except Exception: await arb_session.rollback() print(f"[bold red]Error: Workspace#{i + 1} {workspace.id} processing error[/bold red]") diff --git a/src/apps/shared/commands/patches/m2_6733_add_answer_input_subjects.py b/src/apps/shared/commands/patches/m2_6733_add_answer_input_subjects.py index 78338aabf01..7c010da241c 100644 --- a/src/apps/shared/commands/patches/m2_6733_add_answer_input_subjects.py +++ b/src/apps/shared/commands/patches/m2_6733_add_answer_input_subjects.py @@ -43,8 +43,8 @@ async def main( try: await update_answers(arb_session) await arb_session.commit() - print(f"Processing workspace#{i + 1} {workspace.id} " f"finished") + print(f"Processing workspace#{i + 1} {workspace.id} finished") except Exception: await arb_session.rollback() - print(f"[bold red]Workspace#{i + 1} {workspace.id} " f"processing error[/bold red]") + print(f"[bold red]Workspace#{i + 1} {workspace.id} processing error[/bold red]") raise diff --git a/src/apps/shared/commands/patches/m2_6879_create_deleted_respondents.py b/src/apps/shared/commands/patches/m2_6879_create_deleted_respondents.py index 279014bd5b9..ea6589f8ff3 100644 --- a/src/apps/shared/commands/patches/m2_6879_create_deleted_respondents.py +++ b/src/apps/shared/commands/patches/m2_6879_create_deleted_respondents.py @@ -145,7 +145,7 @@ async def main(session: AsyncSession, *args, **kwargs): try: await find_and_create_missing_roles_arbitrary(session, arb_session, workspace.user_id) await session.commit() - print(f"Processing workspace#{i + 1} {workspace.id} " f"finished") + print(f"Processing workspace#{i + 1} {workspace.id} finished") except Exception: await session.rollback() print(f"[bold red]Error: Workspace#{i + 1} {workspace.id} processing error[/bold red]") diff --git a/src/apps/shared/commands/patches/m2_7203_migrate_secret_ids.py b/src/apps/shared/commands/patches/m2_7203_migrate_secret_ids.py index 7be40abe971..adaeb4be337 100644 --- a/src/apps/shared/commands/patches/m2_7203_migrate_secret_ids.py +++ b/src/apps/shared/commands/patches/m2_7203_migrate_secret_ids.py @@ -16,7 +16,7 @@ from apps.subjects.db.schemas import SubjectSchema MARKER_DELETED = "#deleted#" -UPDATED_AT = datetime.datetime.utcnow().date() +UPDATED_AT = datetime.datetime.now(datetime.UTC).date() def mongoid_to_uuid(id_): diff --git a/src/apps/shared/domain/base.py b/src/apps/shared/domain/base.py index b01d7aeb518..20abd456fb4 100644 --- a/src/apps/shared/domain/base.py +++ b/src/apps/shared/domain/base.py @@ -1,9 +1,10 @@ +import datetime import json import re from typing import TypeVar from pydantic import BaseModel as PBaseModel -from pydantic import Extra +from pydantic import Extra, validator __all__ = [ "InternalModel", @@ -82,6 +83,12 @@ class BaseModel(PBaseModel): def field_alias(cls, field_name: str): return cls.__fields__[field_name].alias + @validator("*", pre=True) + def remove_timezone(cls, v): + if isinstance(v, datetime.datetime): + return v.replace(tzinfo=None) + return v + class InternalModel(BaseModel): class Config: diff --git a/src/apps/shared/domain/custom_validations.py b/src/apps/shared/domain/custom_validations.py index ff096fe81e2..2ee9966dff7 100644 --- a/src/apps/shared/domain/custom_validations.py +++ b/src/apps/shared/domain/custom_validations.py @@ -122,7 +122,7 @@ def datetime_from_ms(value): value > datetime.datetime(year=2000, month=1, day=1, tzinfo=datetime.timezone.utc).timestamp() * 1000 ): # ms, assume date > 2000-01-01 value = value / 1000 # wtf, rework this - return datetime.datetime.utcfromtimestamp(value) + return datetime.datetime.fromtimestamp(value, datetime.UTC) return value diff --git a/src/apps/shared/domain/response/errors.py b/src/apps/shared/domain/response/errors.py index a001384123e..777bbc6ecdc 100644 --- a/src/apps/shared/domain/response/errors.py +++ b/src/apps/shared/domain/response/errors.py @@ -24,7 +24,7 @@ class ErrorResponseMessage(PublicModel): class ErrorResponse(PublicModel): """Error response model.""" - message: str = Field(description="This field represent the objects " "with language-specific errors") + message: str = Field(description="This field represent the objects with language-specific errors") type: str = Field( description="This field represents the business-specific error type", default=ErrorResponseType.UNDEFINED, diff --git a/src/apps/shared/test/base.py b/src/apps/shared/test/base.py index 20f67c174a8..a6ed7544377 100644 --- a/src/apps/shared/test/base.py +++ b/src/apps/shared/test/base.py @@ -49,7 +49,7 @@ async def load_data(self, relative_path: str): values = ",".join(map(_str_caster, datum["fields"].values())) query = text( f""" - insert into "{datum['table']}"({columns}) values ({values}) + insert into "{datum["table"]}"({columns}) values ({values}) """ ) await session.execute(query) diff --git a/src/apps/subjects/crud/subject.py b/src/apps/subjects/crud/subject.py index 57971b667aa..e7d11a17132 100644 --- a/src/apps/subjects/crud/subject.py +++ b/src/apps/subjects/crud/subject.py @@ -1,5 +1,5 @@ import uuid -from datetime import datetime +from datetime import datetime, timezone from asyncpg import UniqueViolationError from sqlalchemy import and_, delete, func, or_, select, update @@ -168,8 +168,8 @@ async def upsert(self, schema: SubjectCreate) -> SubjectSchema | None: index_elements=[SubjectSchema.user_id, SubjectSchema.applet_id], set_={ **values, - "created_at": datetime.utcnow(), - "updated_at": datetime.utcnow(), + "created_at": datetime.now(timezone.utc).replace(tzinfo=None), + "updated_at": datetime.now(timezone.utc).replace(tzinfo=None), }, where=SubjectSchema.soft_exists(exists=False), ).returning(SubjectSchema.id) diff --git a/src/apps/users/commands/token.py b/src/apps/users/commands/token.py index 4b86aaebbf7..db6f6429f0c 100644 --- a/src/apps/users/commands/token.py +++ b/src/apps/users/commands/token.py @@ -21,7 +21,7 @@ async def generate( if ttl: expires_delta = datetime.timedelta(seconds=ttl) - expire = datetime.datetime.utcnow() + expires_delta + expire = datetime.datetime.now(datetime.UTC).replace(tzinfo=None) + expires_delta payload[JWTClaim.exp] = expire access_token = AuthenticationService.create_access_token(payload) diff --git a/src/apps/users/cruds/user.py b/src/apps/users/cruds/user.py index a7e7ee958b6..4d5e91c4f0a 100644 --- a/src/apps/users/cruds/user.py +++ b/src/apps/users/cruds/user.py @@ -90,7 +90,7 @@ async def change_password(self, user: User, update_schema: UserChangePassword) - async def update_last_seen_by_id(self, id_: uuid.UUID) -> None: query = update(UserSchema) query = query.where(UserSchema.id == id_) - query = query.values(last_seen_at=datetime.datetime.utcnow()) + query = query.values(last_seen_at=datetime.datetime.now(datetime.UTC).replace(tzinfo=None)) await self._execute(query) async def exist_by_id(self, id_: uuid.UUID) -> bool: diff --git a/src/apps/users/cruds/user_device.py b/src/apps/users/cruds/user_device.py index 8898de7f73f..1e8baf3940c 100644 --- a/src/apps/users/cruds/user_device.py +++ b/src/apps/users/cruds/user_device.py @@ -27,7 +27,7 @@ async def upsert(self, user_id: uuid.UUID, device_id: str, **data): constraint=UserDeviceSchema.uq_constraint, set_={ **values, - "updated_at": datetime.datetime.utcnow(), + "updated_at": datetime.datetime.now(datetime.UTC).replace(tzinfo=None), }, ) .returning(UserDeviceSchema) diff --git a/src/apps/users/db/schemas.py b/src/apps/users/db/schemas.py index ffd4869988d..403cbef874f 100644 --- a/src/apps/users/db/schemas.py +++ b/src/apps/users/db/schemas.py @@ -1,4 +1,4 @@ -from datetime import datetime +from datetime import datetime, timezone from sqlalchemy import Boolean, Column, DateTime, ForeignKey, String, Text, Unicode, UniqueConstraint from sqlalchemy_utils import StringEncryptedType @@ -15,7 +15,7 @@ class UserSchema(Base): first_name = Column(StringEncryptedType(Unicode, get_key)) last_name = Column(StringEncryptedType(Unicode, get_key)) hashed_password = Column(String(length=100)) - last_seen_at = Column(DateTime(), default=datetime.utcnow) + last_seen_at = Column(DateTime(), default=lambda: datetime.now(timezone.utc).replace(tzinfo=None)) is_super_admin = Column(Boolean(), default=False, server_default="false") is_anonymous_respondent = Column(Boolean(), default=False, server_default="false") is_legacy_deleted_respondent = Column(Boolean(), default=False, server_default="false") diff --git a/src/apps/users/tasks.py b/src/apps/users/tasks.py index 7fe5515cf4b..fd408dd86a3 100644 --- a/src/apps/users/tasks.py +++ b/src/apps/users/tasks.py @@ -81,7 +81,7 @@ async def reencrypt_answers( page += 1 except Exception as e: - msg = f"Reencryption {user_id}: cannot process applet " f"{applet.applet_id}, skip" + msg = f"Reencryption {user_id}: cannot process applet {applet.applet_id}, skip" logger.error(msg) logger.exception(str(e)) async with default_session_maker() as session: diff --git a/src/apps/users/tests/test_password.py b/src/apps/users/tests/test_password.py index ee881b0c9f2..09a1d0d9ed5 100644 --- a/src/apps/users/tests/test_password.py +++ b/src/apps/users/tests/test_password.py @@ -29,7 +29,7 @@ def cache_entry(user: UserCreate): instance=PasswordRecoveryInfoFactory.build( email=user.email, ), - created_at=datetime.datetime.utcnow(), + created_at=datetime.datetime.now(datetime.UTC), ) diff --git a/src/apps/users/tests/test_reencrypt_user_answers.py b/src/apps/users/tests/test_reencrypt_user_answers.py index 9b526398fef..016aff41b7a 100644 --- a/src/apps/users/tests/test_reencrypt_user_answers.py +++ b/src/apps/users/tests/test_reencrypt_user_answers.py @@ -44,8 +44,8 @@ def job_model(user: User) -> Job: creator_id=user.id, status=JobStatus.in_progress, id=uuid.uuid4(), - created_at=datetime.datetime.utcnow(), - updated_at=datetime.datetime.utcnow(), + created_at=datetime.datetime.now(datetime.UTC), + updated_at=datetime.datetime.now(datetime.UTC), ) @@ -89,8 +89,8 @@ def answer_item_create( item_ids=[applet.activities[0].items[0].id], identifier=None, scheduled_time=None, - start_time=datetime.datetime.utcnow(), - end_time=datetime.datetime.utcnow() + datetime.timedelta(seconds=1), + start_time=datetime.datetime.now(datetime.UTC), + end_time=datetime.datetime.now(datetime.UTC) + datetime.timedelta(seconds=1), user_public_key=str(public_key), ) @@ -109,7 +109,7 @@ async def answer( submit_id=uuid.uuid4(), activity_id=applet.activities[0].id, answer=answer_item_create, - created_at=datetime.datetime.utcnow(), + created_at=datetime.datetime.now(datetime.UTC), client=client_meta, consent_to_share=False, ) @@ -132,7 +132,7 @@ async def answer_second( submit_id=uuid.uuid4(), activity_id=applet.activities[0].id, answer=answer_item_create, - created_at=datetime.datetime.utcnow(), + created_at=datetime.datetime.now(datetime.UTC), client=client_meta, consent_to_share=False, ) @@ -156,7 +156,7 @@ async def answer_arbitrary( submit_id=uuid.uuid4(), activity_id=applet.activities[0].id, answer=answer_item_create, - created_at=datetime.datetime.utcnow(), + created_at=datetime.datetime.now(datetime.UTC), client=client_meta, consent_to_share=False, ) @@ -294,7 +294,7 @@ async def test_reencrypt_answers_exception_during_reencrypt_no_retries( spy = mocker.spy(JobService, "change_status") task = await reencrypt_answers.kiq(user.id, user.email_encrypted, user_create.password, "new-pass", retries=0) await task.wait_result() - err_msg = f"Reencryption {user_id}: cannot process applet " f"{applet.id}, skip" + err_msg = f"Reencryption {user_id}: cannot process applet {applet.id}, skip" spy.assert_awaited_once_with(ANY, job_model.id, JobStatus.error, dict(errors=[err_msg, "ERROR"])) answer_after = (await AnswerItemsCRUD(session).get_by_answer_and_activity(answer_id, [act_id_version]))[0].answer assert answer_before == answer_after diff --git a/src/apps/workspaces/crud/user_applet_access.py b/src/apps/workspaces/crud/user_applet_access.py index 33049c775b8..b2f46c1c970 100644 --- a/src/apps/workspaces/crud/user_applet_access.py +++ b/src/apps/workspaces/crud/user_applet_access.py @@ -1,5 +1,5 @@ import uuid -from datetime import datetime +from datetime import datetime, timezone from typing import Tuple from asyncpg.exceptions import UniqueViolationError @@ -217,8 +217,8 @@ async def upsert_user_applet_access(self, schema: UserAppletAccessSchema, where= "applet_id": stmt.excluded.applet_id, "role": stmt.excluded.role, "is_deleted": stmt.excluded.is_deleted, - "created_at": datetime.utcnow(), - "updated_at": datetime.utcnow(), + "created_at": datetime.now(timezone.utc).replace(tzinfo=None), + "updated_at": datetime.now(timezone.utc).replace(tzinfo=None), "meta": stmt.excluded.meta, "nickname": stmt.excluded.nickname, "title": stmt.excluded.title, @@ -228,7 +228,7 @@ async def upsert_user_applet_access(self, schema: UserAppletAccessSchema, where= result = list(await self._execute(stmt)) if not result: - raise UniqueViolationError("duplicate key value violates unique" ' constraint "unique_user_applet_role"') + raise UniqueViolationError('duplicate key value violates unique constraint "unique_user_applet_role"') return result diff --git a/src/apps/workspaces/domain/workspace.py b/src/apps/workspaces/domain/workspace.py index 7abd125e6ee..213ffee2bf6 100644 --- a/src/apps/workspaces/domain/workspace.py +++ b/src/apps/workspaces/domain/workspace.py @@ -376,7 +376,7 @@ def validate_storage_settings(cls, values): required = ["storage_url", "storage_bucket", "storage_access_key"] if required and not all((values[itm] is not None) for itm in required): - raise ValueError(f"{', '.join(required)} are required " f"for {storage_type} storage") + raise ValueError(f"{', '.join(required)} are required for {storage_type} storage") return values diff --git a/src/apps/workspaces/errors.py b/src/apps/workspaces/errors.py index bc350f7ea03..3ba3f245fd5 100644 --- a/src/apps/workspaces/errors.py +++ b/src/apps/workspaces/errors.py @@ -87,7 +87,7 @@ class AppletInviteAccessDenied(AccessDeniedError): class AppletSetScheduleAccessDenied(AccessDeniedError): - message = _("Access denied to manipulate with " "schedules and notifications of the applet.") + message = _("Access denied to manipulate with schedules and notifications of the applet.") class TransferOwnershipAccessDenied(AccessDeniedError): diff --git a/src/apps/workspaces/service/storage.py b/src/apps/workspaces/service/storage.py index f8c0419fc1a..015dbe033de 100644 --- a/src/apps/workspaces/service/storage.py +++ b/src/apps/workspaces/service/storage.py @@ -16,7 +16,7 @@ def __init__( self.client = None def _get_full_path(self, applet_id: uuid.UUID, activity_id: uuid.UUID) -> str: - return f"{self.workspace_id}/" f"{applet_id}/" f"{activity_id}/" f"{self._get_filename()}" + return f"{self.workspace_id}/{applet_id}/{activity_id}/{self._get_filename()}" def _get_filename(self) -> str: return "filename" diff --git a/src/apps/workspaces/tests/test_workspaces.py b/src/apps/workspaces/tests/test_workspaces.py index f117e8b27ee..8217df504c7 100644 --- a/src/apps/workspaces/tests/test_workspaces.py +++ b/src/apps/workspaces/tests/test_workspaces.py @@ -133,10 +133,10 @@ async def tom_answer_applet_one(session, tom: User, applet_one: AppletFull): activity_id=activity.id, answer=ItemAnswerCreate( item_ids=items_ids, - start_time=datetime.datetime.utcnow(), - end_time=datetime.datetime.utcnow(), + start_time=datetime.datetime.now(datetime.UTC).replace(tzinfo=None), + end_time=datetime.datetime.now(datetime.UTC).replace(tzinfo=None), ), - client=ClientMeta(app_id="web", app_version="1.1.0", width="800", height="600"), + client=ClientMeta(app_id="web", app_version="1.1.0", width=800, height=600), target_subject_id=subject.id, source_subject_id=subject.id, consent_to_share=False, @@ -214,7 +214,7 @@ class TestWorkspaces(BaseTest): workspace_respondents_pin = "/workspaces/{owner_id}/respondents/{user_id}/pin" workspace_subject_pin = "/workspaces/{owner_id}/subjects/{subject_id}/pin" workspace_managers_pin = "/workspaces/{owner_id}/managers/{user_id}/pin" - workspace_get_applet_respondent = "/workspaces/{owner_id}" "/applets/{applet_id}" "/respondents/{respondent_id}" + workspace_get_applet_respondent = "/workspaces/{owner_id}/applets/{applet_id}/respondents/{respondent_id}" @pytest.mark.usefixtures("applet_three") async def test_user_workspace_list(self, client, lucy): @@ -1477,7 +1477,7 @@ async def test_user_last_activity_workspace_respondent_retrieve( assert response.status_code == 200, response.json() result = response.json()["result"] date_answer = datetime.datetime.fromisoformat(result["lastSeen"]) - date_now = datetime.datetime.utcnow() + date_now = datetime.datetime.now(datetime.UTC) assert date_now.day == date_answer.day assert date_now.month == date_answer.month assert date_now.year == date_answer.year diff --git a/src/config/database.py b/src/config/database.py index b4e15902958..32b98017b13 100644 --- a/src/config/database.py +++ b/src/config/database.py @@ -11,4 +11,4 @@ class DatabaseSettings(BaseModel): @property def url(self) -> str: - return f"postgresql+asyncpg://{self.user}:{self.password}" f"@{self.host}:{self.port}/{self.db}" + return f"postgresql+asyncpg://{self.user}:{self.password}@{self.host}:{self.port}/{self.db}" diff --git a/src/config/task.py b/src/config/task.py index 10a617a6ea3..ae55b39dff2 100644 --- a/src/config/task.py +++ b/src/config/task.py @@ -14,6 +14,6 @@ class AudioFileConvert(BaseModel): class ImageConvert(BaseModel): - command: str = "convert -strip -interlace JPEG -sampling-factor 4:2:0 " "-quality 85 -colorspace RGB {fin} {fout}" + command: str = "convert -strip -interlace JPEG -sampling-factor 4:2:0 -quality 85 -colorspace RGB {fin} {fout}" subprocess_timeout: int = 20 # sec task_wait_timeout: int = 10 # sec diff --git a/src/infrastructure/app.py b/src/infrastructure/app.py index 4b18ddd8b7e..7e7d7cd5d89 100644 --- a/src/infrastructure/app.py +++ b/src/infrastructure/app.py @@ -93,7 +93,7 @@ def create_app(): # Create base FastAPI application app = FastAPI( - description=f"Commit id: {settings.commit_id}" f"
Version: {settings.version}", + description=f"Commit id: {settings.commit_id}
Version: {settings.version}", debug=settings.debug, ) diff --git a/src/infrastructure/cache/services.py b/src/infrastructure/cache/services.py index f60fc13d6ff..f80890b8379 100644 --- a/src/infrastructure/cache/services.py +++ b/src/infrastructure/cache/services.py @@ -1,6 +1,6 @@ import json from abc import ABC, abstractmethod -from datetime import datetime +from datetime import datetime, timezone from typing import Generic from config import settings @@ -84,7 +84,10 @@ async def set( instance: _InputObject, ttl: int | None = None, ) -> CacheEntry[_InputObject]: - enhanced_cache_entry: CacheEntry[_InputObject] = CacheEntry(instance=instance, created_at=datetime.utcnow()) + enhanced_cache_entry: CacheEntry[_InputObject] = CacheEntry( + instance=instance, + created_at=datetime.now(timezone.utc), + ) await self.redis_client.set( key=self._build_key(key=key), diff --git a/src/infrastructure/database/base.py b/src/infrastructure/database/base.py index 9257c332157..d109b15855e 100644 --- a/src/infrastructure/database/base.py +++ b/src/infrastructure/database/base.py @@ -1,5 +1,5 @@ import uuid -from datetime import datetime +from datetime import datetime, timezone from sqlalchemy import Column, DateTime, MetaData, inspect, text from sqlalchemy.dialects.postgresql import UUID @@ -36,13 +36,13 @@ class Base(SoftDeletable, _Base): # type: ignore ) created_at = Column( DateTime(), - default=datetime.utcnow, + default=lambda: datetime.now(timezone.utc).replace(tzinfo=None), server_default=text("timezone('utc', now())"), ) updated_at = Column( DateTime(), - default=datetime.utcnow, - onupdate=datetime.utcnow, + default=lambda: datetime.now(timezone.utc).replace(tzinfo=None), + onupdate=lambda: datetime.now(timezone.utc).replace(tzinfo=None), server_default=text("timezone('utc', now())"), server_onupdate=text("timezone('utc', now())"), ) diff --git a/src/infrastructure/database/crud.py b/src/infrastructure/database/crud.py index 06c41d29291..5460b9d4a09 100644 --- a/src/infrastructure/database/crud.py +++ b/src/infrastructure/database/crud.py @@ -109,7 +109,7 @@ async def count(self, **filters: Any) -> int: if not isinstance(value, int): raise Exception( - "For some reason count function returned not an integer." f"Value: {value}", + f"For some reason count function returned not an integer.Value: {value}", ) return value diff --git a/src/infrastructure/utility/cdn_arbitrary.py b/src/infrastructure/utility/cdn_arbitrary.py index 949df8af0bf..efe307f74d5 100644 --- a/src/infrastructure/utility/cdn_arbitrary.py +++ b/src/infrastructure/utility/cdn_arbitrary.py @@ -1,5 +1,5 @@ from contextlib import suppress -from datetime import datetime, timedelta +from datetime import datetime, timedelta, timezone from typing import BinaryIO import boto3 @@ -76,7 +76,7 @@ def _check_existence(self, bucket: str, key: str): def _generate_presigned_url(self, key: str): blob_client = self.client.get_blob_client(self.default_container_name, key) permissions = BlobSasPermissions(read=True) - expiration = datetime.utcnow() + timedelta(seconds=self.config.ttl_signed_urls) + expiration = datetime.now(timezone.utc) + timedelta(seconds=self.config.ttl_signed_urls) sas_token = generate_blob_sas( account_name=self.client.account_name, container_name=self.default_container_name, diff --git a/src/infrastructure/utility/redis_client.py b/src/infrastructure/utility/redis_client.py index 89e3d8d0747..c06e9be95a2 100644 --- a/src/infrastructure/utility/redis_client.py +++ b/src/infrastructure/utility/redis_client.py @@ -14,7 +14,7 @@ class RedisCacheTest: _storage: dict = {} async def get(self, key: str): - now = datetime.datetime.utcnow() + now = datetime.datetime.now(datetime.UTC) value, expiry = self._storage.get(key, [None, None]) if not value or (expiry and now > expiry): @@ -23,7 +23,7 @@ async def get(self, key: str): return value async def set(self, name, value, ex=None, **kwargs): - now = datetime.datetime.utcnow() + now = datetime.datetime.now(datetime.UTC) self._storage[name] = [ value, (now + datetime.timedelta(seconds=ex)) if ex else None, @@ -39,7 +39,7 @@ async def keys(self, pattern: str = "*") -> list[str]: pattern = ".+" filtered_keys = [] for key, [_, expire] in self._storage.items(): - if expire and expire < datetime.datetime.utcnow(): + if expire and expire < datetime.datetime.now(datetime.UTC): continue is_match = re.match(pattern, key) if is_match: @@ -50,7 +50,7 @@ async def mget(self, keys) -> list[typing.Any]: results = [] for key in keys: result, expire = self._storage.get(key, [None, None]) - if expire > datetime.datetime.utcnow(): + if expire > datetime.datetime.now(datetime.UTC): results.append(result) return results