diff --git a/.devcontainer/Dockerfile b/.devcontainer/Dockerfile index d86e3124..0041c58d 100644 --- a/.devcontainer/Dockerfile +++ b/.devcontainer/Dockerfile @@ -10,6 +10,3 @@ ENV PYTHONUNBUFFERED 1 # [Optional] Uncomment this section to install additional OS packages. # RUN apt-get update && export DEBIAN_FRONTEND=noninteractive \ # && apt-get -y install --no-install-recommends - - - diff --git a/.github/workflows/linter.yaml b/.github/workflows/linter.yaml new file mode 100644 index 00000000..aa225e94 --- /dev/null +++ b/.github/workflows/linter.yaml @@ -0,0 +1,32 @@ +name: Lint Code Base +on: + pull_request: + branches: + - master +jobs: + build: + if: github.repository == 'coronasafe/ayushma' + name: Lint Code Base + runs-on: ubuntu-latest + permissions: + contents: read + packages: read + statuses: write + steps: + - name: Checkout Code + uses: actions/checkout@v4 + with: + fetch-depth: 0 + - name: Lint Code Base + uses: super-linter/super-linter/slim@v6 + env: + DEFAULT_BRANCH: master + GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }} + VALIDATE_ALL_CODEBASE: false + VALIDATE_PYTHON_BLACK: true + VALIDATE_PYTHON_FLAKE8: true + VALIDATE_PYTHON_ISORT: true + LINTER_RULES_PATH: / + PYTHON_FLAKE8_CONFIG_FILE: "setup.cfg" + PYTHON_BLACK_CONFIG_FILE: "pyproject.toml" + PYTHON_ISORT_CONFIG_FILE: "pyproject.toml" diff --git a/.pre-commit-config.yaml b/.pre-commit-config.yaml index 2b9044e1..3680aa4a 100644 --- a/.pre-commit-config.yaml +++ b/.pre-commit-config.yaml @@ -1,26 +1,26 @@ exclude: "docs|node_modules|migrations|.git|.venv" default_stages: [commit] fail_fast: true - repos: - repo: https://github.com/pre-commit/pre-commit-hooks - rev: v4.3.0 + rev: v4.5.0 hooks: - id: check-yaml - id: end-of-file-fixer - id: trailing-whitespace - repo: https://github.com/PyCQA/isort - rev: 5.12.0 + rev: 5.13.2 hooks: - id: isort - + additional_dependencies: ["isort[pyproject]"] - repo: https://github.com/psf/black - rev: 22.3.0 + rev: 24.3.0 hooks: - id: black - + args: ["--config=pyproject.toml"] - repo: https://github.com/PyCQA/flake8 - rev: 4.0.1 + rev: 7.0.0 hooks: - id: flake8 args: ["--config=setup.cfg"] + additional_dependencies: [flake8-isort] diff --git a/.vscode/settings.json b/.vscode/settings.json index 02714a6b..2e6efc0c 100644 --- a/.vscode/settings.json +++ b/.vscode/settings.json @@ -10,7 +10,7 @@ "[python]": { "editor.defaultFormatter": "ms-python.black-formatter", "editor.codeActionsOnSave": { - "source.organizeImports": true + "source.organizeImports": "explicit" } }, "editor.formatOnSave": true, diff --git a/Makefile b/Makefile index 209e88c2..a9548416 100644 --- a/Makefile +++ b/Makefile @@ -31,7 +31,7 @@ logs: makemigrations: up docker exec django bash -c "python manage.py makemigrations" - + checkmigration: docker compose -f $(docker_config_file) exec django bash -c "python manage.py makemigrations --check --dry-run" diff --git a/Pipfile b/Pipfile index cf7c9ced..db43b4a2 100644 --- a/Pipfile +++ b/Pipfile @@ -53,6 +53,7 @@ factory-boy = "==3.3.0" django-debug-toolbar = "==4.2.0" django-extensions = "==3.2.3" psycopg = {extras = ["binary"], version = "==3.1.17"} +watchdog = "==4.0.0" [requires] python_version = "3.11" diff --git a/Pipfile.lock b/Pipfile.lock index 403bec11..3c9b0163 100644 --- a/Pipfile.lock +++ b/Pipfile.lock @@ -1,7 +1,7 @@ { "_meta": { "hash": { - "sha256": "f7eaea9dba25a601c70a711e0b46fefbee0f7beb7b750012fbd55c55e9bf857f" + "sha256": "63b31ab91cb495e4a97169808cd4de31645b941b2e62433ce1c0d9a7650b2565" }, "pipfile-spec": 6, "requires": { @@ -202,19 +202,19 @@ }, "boto3": { "hashes": [ - "sha256:7bf924c942426839efd7fa5c2c4fe85dba208258393e8017a5ad327c30e5948d", - "sha256:9e62f42de2873baab96eb822386d6a3b1d77f6715cb9033d7b4e6e9ebb0cdbe7" + "sha256:46432fd506708fec6caec4392d758c6f5b79a376dee67d3284fe8b6bfbafeaf4", + "sha256:5c96bed1269f77788780aa2005811dc3a37d4122f08b8e54063a1f4c1b9314a1" ], "markers": "python_version >= '3.8'", - "version": "==1.34.32" + "version": "==1.34.45" }, "botocore": { "hashes": [ - "sha256:466aee158bd0429dbd567c4e2bdf7be9a0a5a74409f8b295c30f34d84c497f9c", - "sha256:aa26a74df83eed3db9542c1cf9108138794c344918b36a506c0723717f1acaab" + "sha256:bf4fe24dd00a6262a27573dea1690ea68eb20f939e7086effadf19aa1acb44d1", + "sha256:e17874ac708fef295d2ea16bb2570ea0512c920de9f25f796de0d8c778f06a02" ], "markers": "python_version >= '3.8'", - "version": "==1.34.32" + "version": "==1.34.45" }, "cachetools": { "hashes": [ @@ -235,11 +235,11 @@ }, "certifi": { "hashes": [ - "sha256:9b469f3a900bf28dc19b8cfbf8019bf47f7fdd1a65a1d4ffb98fc14166beb4d1", - "sha256:e036ab49d5b79556f99cfc2d9320b34cfbe5be05c5871b51de9329f0603b0474" + "sha256:0569859f95fc761b18b45ef421b1290a0f65f147e92a1e5eb3e635f9a5e4e66f", + "sha256:dc383c07b76109f368f6106eee2b593b04a011ea4d55f652c6ca24a754d1cdd1" ], "markers": "python_version >= '3.6'", - "version": "==2023.11.17" + "version": "==2024.2.2" }, "cffi": { "hashes": [ @@ -428,11 +428,11 @@ }, "dataclasses-json": { "hashes": [ - "sha256:35cb40aae824736fdf959801356641836365219cfe14caeb115c39136f775d2a", - "sha256:4aeb343357997396f6bca1acae64e486c3a723d8f5c76301888abeccf0c45176" + "sha256:73696ebf24936560cca79a2430cbc4f3dd23ac7bf46ed17f38e5e5e7657a6377", + "sha256:f90578b8a3177f7552f4e1a6e535e84293cd5da421fcce0642d49c0d7bdf8df2" ], "markers": "python_version >= '3.7' and python_version < '4.0'", - "version": "==0.6.3" + "version": "==0.6.4" }, "distro": { "hashes": [ @@ -536,11 +536,11 @@ }, "dnspython": { "hashes": [ - "sha256:6facdf76b73c742ccf2d07add296f178e629da60be23ce4b0a9c927b1e02c3a6", - "sha256:a0034815a59ba9ae888946be7ccca8f7c157b286f8455b379c692efb51022a15" + "sha256:5ef3b9680161f6fa89daf8ad451b5f1a33b18ae8a1c6778cdf4b43f08c0a6e50", + "sha256:e8f0f9c23a7b7cb99ded64e6c3a6f3e701d78f50c55e002b839dea7225cff7cc" ], "markers": "python_version >= '3.8'", - "version": "==2.5.0" + "version": "==2.6.1" }, "drf-nested-routers": { "hashes": [ @@ -794,11 +794,11 @@ }, "httpcore": { "hashes": [ - "sha256:096cc05bca73b8e459a1fc3dcf585148f63e534eae4339559c9b8a8d6399acc7", - "sha256:9fc092e4799b26174648e54b74ed5f683132a464e95643b226e00c2ed2fa6535" + "sha256:5c0f9546ad17dac4d0772b0808856eb616eb8b48ce94f49ed819fd6982a8a544", + "sha256:9a6a501c3099307d9fd76ac244e08503427679b1e81ceb1d922485e2f2462ad2" ], "markers": "python_version >= '3.8'", - "version": "==1.0.2" + "version": "==1.0.3" }, "httpx": { "hashes": [ @@ -891,19 +891,19 @@ }, "langchain-community": { "hashes": [ - "sha256:ab957b34a562e0199b2ecf050bdc987c4fe889b2ac9f22b75a9fac8b9e30f53a", - "sha256:d503491bbfb691d1b3d10d74f7a69840cee3caf9b58a9a76f053ff925ea76733" + "sha256:bd112b5813702919c50f89b1afa2b63adf1da89999df4842b327ee11220f8c39", + "sha256:c56c48bc77d24e1fc399a9ee9a637d96e3b2ff952e3a080b5a41820d9d00fb3c" ], "markers": "python_version < '4.0' and python_full_version >= '3.8.1'", - "version": "==0.0.17" + "version": "==0.0.20" }, "langchain-core": { "hashes": [ - "sha256:5a60dc3c391b33834fb9c8b072abd7a0df4cbba8ce88eb1bcb288844000ab759", - "sha256:ad470b21cdfdc75e829cd91c8d8eb7e0438ab8ddb5b50828125ff7ada121ee7b" + "sha256:34359cc8b6f8c3d45098c54a6a9b35c9f538ef58329cd943a2249d6d7b4e5806", + "sha256:d42fac013c39a8b0bcd7e337a4cb6c17c16046c60d768f89df582ad73ec3c5cb" ], "markers": "python_version < '4.0' and python_full_version >= '3.8.1'", - "version": "==0.1.18" + "version": "==0.1.23" }, "langchain-experimental": { "hashes": [ @@ -916,11 +916,11 @@ }, "langsmith": { "hashes": [ - "sha256:9d0ccbcda7b69c83828060603a51bb4319e43b8dc807fbd90b6355f8ec709500", - "sha256:fefc631fc30d836b54d4e3f99961c41aea497633898b8f09e305b6c7216c2c54" + "sha256:36c4cc47e5b54be57d038036a30fb19ce6e4c73048cd7a464b8f25b459694d34", + "sha256:8903d3811b9fc89eb18f5961c8e6935fbd2d0f119884fbf30dc70b8f8f4121fc" ], "markers": "python_version < '4.0' and python_full_version >= '3.8.1'", - "version": "==0.0.85" + "version": "==0.0.87" }, "loguru": { "hashes": [ @@ -940,83 +940,99 @@ }, "multidict": { "hashes": [ - "sha256:01a3a55bd90018c9c080fbb0b9f4891db37d148a0a18722b42f94694f8b6d4c9", - "sha256:0b1a97283e0c85772d613878028fec909f003993e1007eafa715b24b377cb9b8", - "sha256:0dfad7a5a1e39c53ed00d2dd0c2e36aed4650936dc18fd9a1826a5ae1cad6f03", - "sha256:11bdf3f5e1518b24530b8241529d2050014c884cf18b6fc69c0c2b30ca248710", - "sha256:1502e24330eb681bdaa3eb70d6358e818e8e8f908a22a1851dfd4e15bc2f8161", - "sha256:16ab77bbeb596e14212e7bab8429f24c1579234a3a462105cda4a66904998664", - "sha256:16d232d4e5396c2efbbf4f6d4df89bfa905eb0d4dc5b3549d872ab898451f569", - "sha256:21a12c4eb6ddc9952c415f24eef97e3e55ba3af61f67c7bc388dcdec1404a067", - "sha256:27c523fbfbdfd19c6867af7346332b62b586eed663887392cff78d614f9ec313", - "sha256:281af09f488903fde97923c7744bb001a9b23b039a909460d0f14edc7bf59706", - "sha256:33029f5734336aa0d4c0384525da0387ef89148dc7191aae00ca5fb23d7aafc2", - "sha256:3601a3cece3819534b11d4efc1eb76047488fddd0c85a3948099d5da4d504636", - "sha256:3666906492efb76453c0e7b97f2cf459b0682e7402c0489a95484965dbc1da49", - "sha256:36c63aaa167f6c6b04ef2c85704e93af16c11d20de1d133e39de6a0e84582a93", - "sha256:39ff62e7d0f26c248b15e364517a72932a611a9b75f35b45be078d81bdb86603", - "sha256:43644e38f42e3af682690876cff722d301ac585c5b9e1eacc013b7a3f7b696a0", - "sha256:4372381634485bec7e46718edc71528024fcdc6f835baefe517b34a33c731d60", - "sha256:458f37be2d9e4c95e2d8866a851663cbc76e865b78395090786f6cd9b3bbf4f4", - "sha256:45e1ecb0379bfaab5eef059f50115b54571acfbe422a14f668fc8c27ba410e7e", - "sha256:4b9d9e4e2b37daddb5c23ea33a3417901fa7c7b3dee2d855f63ee67a0b21e5b1", - "sha256:4ceef517eca3e03c1cceb22030a3e39cb399ac86bff4e426d4fc6ae49052cc60", - "sha256:4d1a3d7ef5e96b1c9e92f973e43aa5e5b96c659c9bc3124acbbd81b0b9c8a951", - "sha256:4dcbb0906e38440fa3e325df2359ac6cb043df8e58c965bb45f4e406ecb162cc", - "sha256:509eac6cf09c794aa27bcacfd4d62c885cce62bef7b2c3e8b2e49d365b5003fe", - "sha256:52509b5be062d9eafc8170e53026fbc54cf3b32759a23d07fd935fb04fc22d95", - "sha256:52f2dffc8acaba9a2f27174c41c9e57f60b907bb9f096b36b1a1f3be71c6284d", - "sha256:574b7eae1ab267e5f8285f0fe881f17efe4b98c39a40858247720935b893bba8", - "sha256:5979b5632c3e3534e42ca6ff856bb24b2e3071b37861c2c727ce220d80eee9ed", - "sha256:59d43b61c59d82f2effb39a93c48b845efe23a3852d201ed2d24ba830d0b4cf2", - "sha256:5a4dcf02b908c3b8b17a45fb0f15b695bf117a67b76b7ad18b73cf8e92608775", - "sha256:5cad9430ab3e2e4fa4a2ef4450f548768400a2ac635841bc2a56a2052cdbeb87", - "sha256:5fc1b16f586f049820c5c5b17bb4ee7583092fa0d1c4e28b5239181ff9532e0c", - "sha256:62501642008a8b9871ddfccbf83e4222cf8ac0d5aeedf73da36153ef2ec222d2", - "sha256:64bdf1086b6043bf519869678f5f2757f473dee970d7abf6da91ec00acb9cb98", - "sha256:64da238a09d6039e3bd39bb3aee9c21a5e34f28bfa5aa22518581f910ff94af3", - "sha256:666daae833559deb2d609afa4490b85830ab0dfca811a98b70a205621a6109fe", - "sha256:67040058f37a2a51ed8ea8f6b0e6ee5bd78ca67f169ce6122f3e2ec80dfe9b78", - "sha256:6748717bb10339c4760c1e63da040f5f29f5ed6e59d76daee30305894069a660", - "sha256:6b181d8c23da913d4ff585afd1155a0e1194c0b50c54fcfe286f70cdaf2b7176", - "sha256:6ed5f161328b7df384d71b07317f4d8656434e34591f20552c7bcef27b0ab88e", - "sha256:7582a1d1030e15422262de9f58711774e02fa80df0d1578995c76214f6954988", - "sha256:7d18748f2d30f94f498e852c67d61261c643b349b9d2a581131725595c45ec6c", - "sha256:7d6ae9d593ef8641544d6263c7fa6408cc90370c8cb2bbb65f8d43e5b0351d9c", - "sha256:81a4f0b34bd92df3da93315c6a59034df95866014ac08535fc819f043bfd51f0", - "sha256:8316a77808c501004802f9beebde51c9f857054a0c871bd6da8280e718444449", - "sha256:853888594621e6604c978ce2a0444a1e6e70c8d253ab65ba11657659dcc9100f", - "sha256:99b76c052e9f1bc0721f7541e5e8c05db3941eb9ebe7b8553c625ef88d6eefde", - "sha256:a2e4369eb3d47d2034032a26c7a80fcb21a2cb22e1173d761a162f11e562caa5", - "sha256:ab55edc2e84460694295f401215f4a58597f8f7c9466faec545093045476327d", - "sha256:af048912e045a2dc732847d33821a9d84ba553f5c5f028adbd364dd4765092ac", - "sha256:b1a2eeedcead3a41694130495593a559a668f382eee0727352b9a41e1c45759a", - "sha256:b1e8b901e607795ec06c9e42530788c45ac21ef3aaa11dbd0c69de543bfb79a9", - "sha256:b41156839806aecb3641f3208c0dafd3ac7775b9c4c422d82ee2a45c34ba81ca", - "sha256:b692f419760c0e65d060959df05f2a531945af31fda0c8a3b3195d4efd06de11", - "sha256:bc779e9e6f7fda81b3f9aa58e3a6091d49ad528b11ed19f6621408806204ad35", - "sha256:bf6774e60d67a9efe02b3616fee22441d86fab4c6d335f9d2051d19d90a40063", - "sha256:c048099e4c9e9d615545e2001d3d8a4380bd403e1a0578734e0d31703d1b0c0b", - "sha256:c5cb09abb18c1ea940fb99360ea0396f34d46566f157122c92dfa069d3e0e982", - "sha256:cc8e1d0c705233c5dd0c5e6460fbad7827d5d36f310a0fadfd45cc3029762258", - "sha256:d5e3fc56f88cc98ef8139255cf8cd63eb2c586531e43310ff859d6bb3a6b51f1", - "sha256:d6aa0418fcc838522256761b3415822626f866758ee0bc6632c9486b179d0b52", - "sha256:d6c254ba6e45d8e72739281ebc46ea5eb5f101234f3ce171f0e9f5cc86991480", - "sha256:d6d635d5209b82a3492508cf5b365f3446afb65ae7ebd755e70e18f287b0adf7", - "sha256:dcfe792765fab89c365123c81046ad4103fcabbc4f56d1c1997e6715e8015461", - "sha256:ddd3915998d93fbcd2566ddf9cf62cdb35c9e093075f862935573d265cf8f65d", - "sha256:ddff9c4e225a63a5afab9dd15590432c22e8057e1a9a13d28ed128ecf047bbdc", - "sha256:e41b7e2b59679edfa309e8db64fdf22399eec4b0b24694e1b2104fb789207779", - "sha256:e69924bfcdda39b722ef4d9aa762b2dd38e4632b3641b1d9a57ca9cd18f2f83a", - "sha256:ea20853c6dbbb53ed34cb4d080382169b6f4554d394015f1bef35e881bf83547", - "sha256:ee2a1ece51b9b9e7752e742cfb661d2a29e7bcdba2d27e66e28a99f1890e4fa0", - "sha256:eeb6dcc05e911516ae3d1f207d4b0520d07f54484c49dfc294d6e7d63b734171", - "sha256:f70b98cd94886b49d91170ef23ec5c0e8ebb6f242d734ed7ed677b24d50c82cf", - "sha256:fc35cb4676846ef752816d5be2193a1e8367b4c1397b74a565a9d0389c433a1d", - "sha256:ff959bee35038c4624250473988b24f846cbeb2c6639de3602c073f10410ceba" + "sha256:01265f5e40f5a17f8241d52656ed27192be03bfa8764d88e8220141d1e4b3556", + "sha256:0275e35209c27a3f7951e1ce7aaf93ce0d163b28948444bec61dd7badc6d3f8c", + "sha256:04bde7a7b3de05732a4eb39c94574db1ec99abb56162d6c520ad26f83267de29", + "sha256:04da1bb8c8dbadf2a18a452639771951c662c5ad03aefe4884775454be322c9b", + "sha256:09a892e4a9fb47331da06948690ae38eaa2426de97b4ccbfafbdcbe5c8f37ff8", + "sha256:0d63c74e3d7ab26de115c49bffc92cc77ed23395303d496eae515d4204a625e7", + "sha256:107c0cdefe028703fb5dafe640a409cb146d44a6ae201e55b35a4af8e95457dd", + "sha256:141b43360bfd3bdd75f15ed811850763555a251e38b2405967f8e25fb43f7d40", + "sha256:14c2976aa9038c2629efa2c148022ed5eb4cb939e15ec7aace7ca932f48f9ba6", + "sha256:19fe01cea168585ba0f678cad6f58133db2aa14eccaf22f88e4a6dccadfad8b3", + "sha256:1d147090048129ce3c453f0292e7697d333db95e52616b3793922945804a433c", + "sha256:1d9ea7a7e779d7a3561aade7d596649fbecfa5c08a7674b11b423783217933f9", + "sha256:215ed703caf15f578dca76ee6f6b21b7603791ae090fbf1ef9d865571039ade5", + "sha256:21fd81c4ebdb4f214161be351eb5bcf385426bf023041da2fd9e60681f3cebae", + "sha256:220dd781e3f7af2c2c1053da9fa96d9cf3072ca58f057f4c5adaaa1cab8fc442", + "sha256:228b644ae063c10e7f324ab1ab6b548bdf6f8b47f3ec234fef1093bc2735e5f9", + "sha256:29bfeb0dff5cb5fdab2023a7a9947b3b4af63e9c47cae2a10ad58394b517fddc", + "sha256:2f4848aa3baa109e6ab81fe2006c77ed4d3cd1e0ac2c1fbddb7b1277c168788c", + "sha256:2faa5ae9376faba05f630d7e5e6be05be22913782b927b19d12b8145968a85ea", + "sha256:2ffc42c922dbfddb4a4c3b438eb056828719f07608af27d163191cb3e3aa6cc5", + "sha256:37b15024f864916b4951adb95d3a80c9431299080341ab9544ed148091b53f50", + "sha256:3cc2ad10255f903656017363cd59436f2111443a76f996584d1077e43ee51182", + "sha256:3d25f19500588cbc47dc19081d78131c32637c25804df8414463ec908631e453", + "sha256:403c0911cd5d5791605808b942c88a8155c2592e05332d2bf78f18697a5fa15e", + "sha256:411bf8515f3be9813d06004cac41ccf7d1cd46dfe233705933dd163b60e37600", + "sha256:425bf820055005bfc8aa9a0b99ccb52cc2f4070153e34b701acc98d201693733", + "sha256:435a0984199d81ca178b9ae2c26ec3d49692d20ee29bc4c11a2a8d4514c67eda", + "sha256:4a6a4f196f08c58c59e0b8ef8ec441d12aee4125a7d4f4fef000ccb22f8d7241", + "sha256:4cc0ef8b962ac7a5e62b9e826bd0cd5040e7d401bc45a6835910ed699037a461", + "sha256:51d035609b86722963404f711db441cf7134f1889107fb171a970c9701f92e1e", + "sha256:53689bb4e102200a4fafa9de9c7c3c212ab40a7ab2c8e474491914d2305f187e", + "sha256:55205d03e8a598cfc688c71ca8ea5f66447164efff8869517f175ea632c7cb7b", + "sha256:5c0631926c4f58e9a5ccce555ad7747d9a9f8b10619621f22f9635f069f6233e", + "sha256:5cb241881eefd96b46f89b1a056187ea8e9ba14ab88ba632e68d7a2ecb7aadf7", + "sha256:60d698e8179a42ec85172d12f50b1668254628425a6bd611aba022257cac1386", + "sha256:612d1156111ae11d14afaf3a0669ebf6c170dbb735e510a7438ffe2369a847fd", + "sha256:6214c5a5571802c33f80e6c84713b2c79e024995b9c5897f794b43e714daeec9", + "sha256:6939c95381e003f54cd4c5516740faba40cf5ad3eeff460c3ad1d3e0ea2549bf", + "sha256:69db76c09796b313331bb7048229e3bee7928eb62bab5e071e9f7fcc4879caee", + "sha256:6bf7a982604375a8d49b6cc1b781c1747f243d91b81035a9b43a2126c04766f5", + "sha256:766c8f7511df26d9f11cd3a8be623e59cca73d44643abab3f8c8c07620524e4a", + "sha256:76c0de87358b192de7ea9649beb392f107dcad9ad27276324c24c91774ca5271", + "sha256:76f067f5121dcecf0d63a67f29080b26c43c71a98b10c701b0677e4a065fbd54", + "sha256:7901c05ead4b3fb75113fb1dd33eb1253c6d3ee37ce93305acd9d38e0b5f21a4", + "sha256:79660376075cfd4b2c80f295528aa6beb2058fd289f4c9252f986751a4cd0496", + "sha256:79a6d2ba910adb2cbafc95dad936f8b9386e77c84c35bc0add315b856d7c3abb", + "sha256:7afcdd1fc07befad18ec4523a782cde4e93e0a2bf71239894b8d61ee578c1319", + "sha256:7be7047bd08accdb7487737631d25735c9a04327911de89ff1b26b81745bd4e3", + "sha256:7c6390cf87ff6234643428991b7359b5f59cc15155695deb4eda5c777d2b880f", + "sha256:7df704ca8cf4a073334e0427ae2345323613e4df18cc224f647f251e5e75a527", + "sha256:85f67aed7bb647f93e7520633d8f51d3cbc6ab96957c71272b286b2f30dc70ed", + "sha256:896ebdcf62683551312c30e20614305f53125750803b614e9e6ce74a96232604", + "sha256:92d16a3e275e38293623ebf639c471d3e03bb20b8ebb845237e0d3664914caef", + "sha256:99f60d34c048c5c2fabc766108c103612344c46e35d4ed9ae0673d33c8fb26e8", + "sha256:9fe7b0653ba3d9d65cbe7698cca585bf0f8c83dbbcc710db9c90f478e175f2d5", + "sha256:a3145cb08d8625b2d3fee1b2d596a8766352979c9bffe5d7833e0503d0f0b5e5", + "sha256:aeaf541ddbad8311a87dd695ed9642401131ea39ad7bc8cf3ef3967fd093b626", + "sha256:b55358304d7a73d7bdf5de62494aaf70bd33015831ffd98bc498b433dfe5b10c", + "sha256:b82cc8ace10ab5bd93235dfaab2021c70637005e1ac787031f4d1da63d493c1d", + "sha256:c0868d64af83169e4d4152ec612637a543f7a336e4a307b119e98042e852ad9c", + "sha256:c1c1496e73051918fcd4f58ff2e0f2f3066d1c76a0c6aeffd9b45d53243702cc", + "sha256:c9bf56195c6bbd293340ea82eafd0071cb3d450c703d2c93afb89f93b8386ccc", + "sha256:cbebcd5bcaf1eaf302617c114aa67569dd3f090dd0ce8ba9e35e9985b41ac35b", + "sha256:cd6c8fca38178e12c00418de737aef1261576bd1b6e8c6134d3e729a4e858b38", + "sha256:ceb3b7e6a0135e092de86110c5a74e46bda4bd4fbfeeb3a3bcec79c0f861e450", + "sha256:cf590b134eb70629e350691ecca88eac3e3b8b3c86992042fb82e3cb1830d5e1", + "sha256:d3eb1ceec286eba8220c26f3b0096cf189aea7057b6e7b7a2e60ed36b373b77f", + "sha256:d65f25da8e248202bd47445cec78e0025c0fe7582b23ec69c3b27a640dd7a8e3", + "sha256:d6f6d4f185481c9669b9447bf9d9cf3b95a0e9df9d169bbc17e363b7d5487755", + "sha256:d84a5c3a5f7ce6db1f999fb9438f686bc2e09d38143f2d93d8406ed2dd6b9226", + "sha256:d946b0a9eb8aaa590df1fe082cee553ceab173e6cb5b03239716338629c50c7a", + "sha256:dce1c6912ab9ff5f179eaf6efe7365c1f425ed690b03341911bf4939ef2f3046", + "sha256:de170c7b4fe6859beb8926e84f7d7d6c693dfe8e27372ce3b76f01c46e489fcf", + "sha256:e02021f87a5b6932fa6ce916ca004c4d441509d33bbdbeca70d05dff5e9d2479", + "sha256:e030047e85cbcedbfc073f71836d62dd5dadfbe7531cae27789ff66bc551bd5e", + "sha256:e0e79d91e71b9867c73323a3444724d496c037e578a0e1755ae159ba14f4f3d1", + "sha256:e4428b29611e989719874670fd152b6625500ad6c686d464e99f5aaeeaca175a", + "sha256:e4972624066095e52b569e02b5ca97dbd7a7ddd4294bf4e7247d52635630dd83", + "sha256:e7be68734bd8c9a513f2b0cfd508802d6609da068f40dc57d4e3494cefc92929", + "sha256:e8e94e6912639a02ce173341ff62cc1201232ab86b8a8fcc05572741a5dc7d93", + "sha256:ea1456df2a27c73ce51120fa2f519f1bea2f4a03a917f4a43c8707cf4cbbae1a", + "sha256:ebd8d160f91a764652d3e51ce0d2956b38efe37c9231cd82cfc0bed2e40b581c", + "sha256:eca2e9d0cc5a889850e9bbd68e98314ada174ff6ccd1129500103df7a94a7a44", + "sha256:edd08e6f2f1a390bf137080507e44ccc086353c8e98c657e666c017718561b89", + "sha256:f285e862d2f153a70586579c15c44656f888806ed0e5b56b64489afe4a2dbfba", + "sha256:f2a1dee728b52b33eebff5072817176c172050d44d67befd681609b4746e1c2e", + "sha256:f7e301075edaf50500f0b341543c41194d8df3ae5caf4702f2095f3ca73dd8da", + "sha256:fb616be3538599e797a2017cccca78e354c767165e8858ab5116813146041a24", + "sha256:fce28b3c8a81b6b36dfac9feb1de115bab619b3c13905b419ec71d03a3fc1423", + "sha256:fe5d7785250541f7f5019ab9cba2c71169dc7d74d0f45253f8313f436458a4ef" ], "markers": "python_version >= '3.7'", - "version": "==6.0.4" + "version": "==6.0.5" }, "mypy-extensions": { "hashes": [ @@ -1037,45 +1053,45 @@ }, "numpy": { "hashes": [ - "sha256:02f98011ba4ab17f46f80f7f8f1c291ee7d855fcef0a5a98db80767a468c85cd", - "sha256:0b7e807d6888da0db6e7e75838444d62495e2b588b99e90dd80c3459594e857b", - "sha256:12c70ac274b32bc00c7f61b515126c9205323703abb99cd41836e8125ea0043e", - "sha256:1666f634cb3c80ccbd77ec97bc17337718f56d6658acf5d3b906ca03e90ce87f", - "sha256:18c3319a7d39b2c6a9e3bb75aab2304ab79a811ac0168a671a62e6346c29b03f", - "sha256:211ddd1e94817ed2d175b60b6374120244a4dd2287f4ece45d49228b4d529178", - "sha256:21a9484e75ad018974a2fdaa216524d64ed4212e418e0a551a2d83403b0531d3", - "sha256:39763aee6dfdd4878032361b30b2b12593fb445ddb66bbac802e2113eb8a6ac4", - "sha256:3c67423b3703f8fbd90f5adaa37f85b5794d3366948efe9a5190a5f3a83fc34e", - "sha256:46f47ee566d98849323f01b349d58f2557f02167ee301e5e28809a8c0e27a2d0", - "sha256:51c7f1b344f302067b02e0f5b5d2daa9ed4a721cf49f070280ac202738ea7f00", - "sha256:5f24750ef94d56ce6e33e4019a8a4d68cfdb1ef661a52cdaee628a56d2437419", - "sha256:697df43e2b6310ecc9d95f05d5ef20eacc09c7c4ecc9da3f235d39e71b7da1e4", - "sha256:6d45b3ec2faed4baca41c76617fcdcfa4f684ff7a151ce6fc78ad3b6e85af0a6", - "sha256:77810ef29e0fb1d289d225cabb9ee6cf4d11978a00bb99f7f8ec2132a84e0166", - "sha256:7ca4f24341df071877849eb2034948459ce3a07915c2734f1abb4018d9c49d7b", - "sha256:7f784e13e598e9594750b2ef6729bcd5a47f6cfe4a12cca13def35e06d8163e3", - "sha256:806dd64230dbbfaca8a27faa64e2f414bf1c6622ab78cc4264f7f5f028fee3bf", - "sha256:867e3644e208c8922a3be26fc6bbf112a035f50f0a86497f98f228c50c607bb2", - "sha256:8c66d6fec467e8c0f975818c1796d25c53521124b7cfb760114be0abad53a0a2", - "sha256:8ed07a90f5450d99dad60d3799f9c03c6566709bd53b497eb9ccad9a55867f36", - "sha256:9bc6d1a7f8cedd519c4b7b1156d98e051b726bf160715b769106661d567b3f03", - "sha256:9e1591f6ae98bcfac2a4bbf9221c0b92ab49762228f38287f6eeb5f3f55905ce", - "sha256:9e87562b91f68dd8b1c39149d0323b42e0082db7ddb8e934ab4c292094d575d6", - "sha256:a7081fd19a6d573e1a05e600c82a1c421011db7935ed0d5c483e9dd96b99cf13", - "sha256:a8474703bffc65ca15853d5fd4d06b18138ae90c17c8d12169968e998e448bb5", - "sha256:af36e0aa45e25c9f57bf684b1175e59ea05d9a7d3e8e87b7ae1a1da246f2767e", - "sha256:b1240f767f69d7c4c8a29adde2310b871153df9b26b5cb2b54a561ac85146485", - "sha256:b4d362e17bcb0011738c2d83e0a65ea8ce627057b2fdda37678f4374a382a137", - "sha256:b831295e5472954104ecb46cd98c08b98b49c69fdb7040483aff799a755a7374", - "sha256:b8c275f0ae90069496068c714387b4a0eba5d531aace269559ff2b43655edd58", - "sha256:bdd2b45bf079d9ad90377048e2747a0c82351989a2165821f0c96831b4a2a54b", - "sha256:cc0743f0302b94f397a4a65a660d4cd24267439eb16493fb3caad2e4389bccbb", - "sha256:da4b0c6c699a0ad73c810736303f7fbae483bcb012e38d7eb06a5e3b432c981b", - "sha256:f25e2811a9c932e43943a2615e65fc487a0b6b49218899e62e426e7f0a57eeda", - "sha256:f73497e8c38295aaa4741bdfa4fda1a5aedda5473074369eca10626835445511" + "sha256:03a8c78d01d9781b28a6989f6fa1bb2c4f2d51201cf99d3dd875df6fbd96b23b", + "sha256:08beddf13648eb95f8d867350f6a018a4be2e5ad54c8d8caed89ebca558b2818", + "sha256:1af303d6b2210eb850fcf03064d364652b7120803a0b872f5211f5234b399f20", + "sha256:1dda2e7b4ec9dd512f84935c5f126c8bd8b9f2fc001e9f54af255e8c5f16b0e0", + "sha256:2a02aba9ed12e4ac4eb3ea9421c420301a0c6460d9830d74a9df87efa4912010", + "sha256:2e4ee3380d6de9c9ec04745830fd9e2eccb3e6cf790d39d7b98ffd19b0dd754a", + "sha256:3373d5d70a5fe74a2c1bb6d2cfd9609ecf686d47a2d7b1d37a8f3b6bf6003aea", + "sha256:47711010ad8555514b434df65f7d7b076bb8261df1ca9bb78f53d3b2db02e95c", + "sha256:4c66707fabe114439db9068ee468c26bbdf909cac0fb58686a42a24de1760c71", + "sha256:50193e430acfc1346175fcbdaa28ffec49947a06918b7b92130744e81e640110", + "sha256:52b8b60467cd7dd1e9ed082188b4e6bb35aa5cdd01777621a1658910745b90be", + "sha256:60dedbb91afcbfdc9bc0b1f3f402804070deed7392c23eb7a7f07fa857868e8a", + "sha256:62b8e4b1e28009ef2846b4c7852046736bab361f7aeadeb6a5b89ebec3c7055a", + "sha256:666dbfb6ec68962c033a450943ded891bed2d54e6755e35e5835d63f4f6931d5", + "sha256:675d61ffbfa78604709862923189bad94014bef562cc35cf61d3a07bba02a7ed", + "sha256:679b0076f67ecc0138fd2ede3a8fd196dddc2ad3254069bcb9faf9a79b1cebcd", + "sha256:7349ab0fa0c429c82442a27a9673fc802ffdb7c7775fad780226cb234965e53c", + "sha256:7ab55401287bfec946ced39700c053796e7cc0e3acbef09993a9ad2adba6ca6e", + "sha256:7e50d0a0cc3189f9cb0aeb3a6a6af18c16f59f004b866cd2be1c14b36134a4a0", + "sha256:95a7476c59002f2f6c590b9b7b998306fba6a5aa646b1e22ddfeaf8f78c3a29c", + "sha256:96ff0b2ad353d8f990b63294c8986f1ec3cb19d749234014f4e7eb0112ceba5a", + "sha256:9fad7dcb1aac3c7f0584a5a8133e3a43eeb2fe127f47e3632d43d677c66c102b", + "sha256:9ff0f4f29c51e2803569d7a51c2304de5554655a60c5d776e35b4a41413830d0", + "sha256:a354325ee03388678242a4d7ebcd08b5c727033fcff3b2f536aea978e15ee9e6", + "sha256:a4abb4f9001ad2858e7ac189089c42178fcce737e4169dc61321660f1a96c7d2", + "sha256:ab47dbe5cc8210f55aa58e4805fe224dac469cde56b9f731a4c098b91917159a", + "sha256:afedb719a9dcfc7eaf2287b839d8198e06dcd4cb5d276a3df279231138e83d30", + "sha256:b3ce300f3644fb06443ee2222c2201dd3a89ea6040541412b8fa189341847218", + "sha256:b97fe8060236edf3662adfc2c633f56a08ae30560c56310562cb4f95500022d5", + "sha256:bfe25acf8b437eb2a8b2d49d443800a5f18508cd811fea3181723922a8a82b07", + "sha256:cd25bcecc4974d09257ffcd1f098ee778f7834c3ad767fe5db785be9a4aa9cb2", + "sha256:d209d8969599b27ad20994c8e41936ee0964e6da07478d6c35016bc386b66ad4", + "sha256:d5241e0a80d808d70546c697135da2c613f30e28251ff8307eb72ba696945764", + "sha256:edd8b5fe47dab091176d21bb6de568acdd906d1887a4584a15a9a96a1dca06ef", + "sha256:f870204a840a60da0b12273ef34f7051e98c3b5961b61b0c2c1be6dfd64fbcd3", + "sha256:ffa75af20b44f8dba823498024771d5ac50620e6915abac414251bd971b4529f" ], "markers": "python_version >= '3.9'", - "version": "==1.26.3" + "version": "==1.26.4" }, "openai": { "hashes": [ @@ -1191,20 +1207,20 @@ }, "protobuf": { "hashes": [ - "sha256:10894a2885b7175d3984f2be8d9850712c57d5e7587a2410720af8be56cdaf62", - "sha256:2db9f8fa64fbdcdc93767d3cf81e0f2aef176284071507e3ede160811502fd3d", - "sha256:33a1aeef4b1927431d1be780e87b641e322b88d654203a9e9d93f218ee359e61", - "sha256:47f3de503fe7c1245f6f03bea7e8d3ec11c6c4a2ea9ef910e3221c8a15516d62", - "sha256:5e5c933b4c30a988b52e0b7c02641760a5ba046edc5e43d3b94a74c9fc57c1b3", - "sha256:8f62574857ee1de9f770baf04dde4165e30b15ad97ba03ceac65f760ff018ac9", - "sha256:a8b7a98d4ce823303145bf3c1a8bdb0f2f4642a414b196f04ad9853ed0c8f830", - "sha256:b50c949608682b12efb0b2717f53256f03636af5f60ac0c1d900df6213910fd6", - "sha256:d66a769b8d687df9024f2985d5137a337f957a0916cf5464d1513eee96a63ff0", - "sha256:fc381d1dd0516343f1440019cedf08a7405f791cd49eef4ae1ea06520bc1c020", - "sha256:fe599e175cb347efc8ee524bcd4b902d11f7262c0e569ececcb89995c15f0a5e" + "sha256:19b270aeaa0099f16d3ca02628546b8baefe2955bbe23224aaf856134eccf1e4", + "sha256:209ba4cc916bab46f64e56b85b090607a676f66b473e6b762e6f1d9d591eb2e8", + "sha256:25b5d0b42fd000320bd7830b349e3b696435f3b329810427a6bcce6a5492cc5c", + "sha256:7c8daa26095f82482307bc717364e7c13f4f1c99659be82890dcfc215194554d", + "sha256:c053062984e61144385022e53678fbded7aea14ebb3e0305ae3592fb219ccfa4", + "sha256:d4198877797a83cbfe9bffa3803602bbe1625dc30d8a097365dbc762e5790faa", + "sha256:e3c97a1555fd6388f857770ff8b9703083de6bf1f9274a002a332d65fbb56c8c", + "sha256:e7cb0ae90dd83727f0c0718634ed56837bfeeee29a5f82a7514c03ee1364c019", + "sha256:f0700d54bcf45424477e46a9f0944155b46fb0639d69728739c0e47bab83f2b9", + "sha256:f1279ab38ecbfae7e456a108c5c0681e4956d5b1090027c1de0f934dfdb4b35c", + "sha256:f4f118245c4a087776e0a8408be33cf09f6c547442c00395fbfb116fac2f8ac2" ], "markers": "python_version >= '3.8'", - "version": "==4.25.2" + "version": "==4.25.3" }, "psycopg": { "extras": [ @@ -1248,96 +1264,96 @@ }, "pydantic": { "hashes": [ - "sha256:1440966574e1b5b99cf75a13bec7b20e3512e8a61b894ae252f56275e2c465ae", - "sha256:ae887bd94eb404b09d86e4d12f93893bdca79d766e738528c6fa1c849f3c6bcf" + "sha256:0b6a909df3192245cb736509a92ff69e4fef76116feffec68e93a567347bae6f", + "sha256:4fd5c182a2488dc63e6d32737ff19937888001e2a6d86e94b3f233104a5d1fa9" ], "markers": "python_version >= '3.8'", - "version": "==2.6.0" + "version": "==2.6.1" }, "pydantic-core": { "hashes": [ - "sha256:06f0d5a1d9e1b7932477c172cc720b3b23c18762ed7a8efa8398298a59d177c7", - "sha256:07982b82d121ed3fc1c51faf6e8f57ff09b1325d2efccaa257dd8c0dd937acca", - "sha256:0f478ec204772a5c8218e30eb813ca43e34005dff2eafa03931b3d8caef87d51", - "sha256:102569d371fadc40d8f8598a59379c37ec60164315884467052830b28cc4e9da", - "sha256:10dca874e35bb60ce4f9f6665bfbfad050dd7573596608aeb9e098621ac331dc", - "sha256:150ba5c86f502c040b822777e2e519b5625b47813bd05f9273a8ed169c97d9ae", - "sha256:1661c668c1bb67b7cec96914329d9ab66755911d093bb9063c4c8914188af6d4", - "sha256:1a2fe7b00a49b51047334d84aafd7e39f80b7675cad0083678c58983662da89b", - "sha256:1ae8048cba95f382dba56766525abca438328455e35c283bb202964f41a780b0", - "sha256:20f724a023042588d0f4396bbbcf4cffd0ddd0ad3ed4f0d8e6d4ac4264bae81e", - "sha256:2133b0e412a47868a358713287ff9f9a328879da547dc88be67481cdac529118", - "sha256:21e3298486c4ea4e4d5cc6fb69e06fb02a4e22089304308817035ac006a7f506", - "sha256:21ebaa4bf6386a3b22eec518da7d679c8363fb7fb70cf6972161e5542f470798", - "sha256:23632132f1fd608034f1a56cc3e484be00854db845b3a4a508834be5a6435a6f", - "sha256:2d5bea8012df5bb6dda1e67d0563ac50b7f64a5d5858348b5c8cb5043811c19d", - "sha256:300616102fb71241ff477a2cbbc847321dbec49428434a2f17f37528721c4948", - "sha256:30a8259569fbeec49cfac7fda3ec8123486ef1b729225222f0d41d5f840b476f", - "sha256:399166f24c33a0c5759ecc4801f040dbc87d412c1a6d6292b2349b4c505effc9", - "sha256:3fac641bbfa43d5a1bed99d28aa1fded1984d31c670a95aac1bf1d36ac6ce137", - "sha256:42c29d54ed4501a30cd71015bf982fa95e4a60117b44e1a200290ce687d3e640", - "sha256:462d599299c5971f03c676e2b63aa80fec5ebc572d89ce766cd11ca8bcb56f3f", - "sha256:4eebbd049008eb800f519578e944b8dc8e0f7d59a5abb5924cc2d4ed3a1834ff", - "sha256:502c062a18d84452858f8aea1e520e12a4d5228fc3621ea5061409d666ea1706", - "sha256:5317c04349472e683803da262c781c42c5628a9be73f4750ac7d13040efb5d2d", - "sha256:5511f962dd1b9b553e9534c3b9c6a4b0c9ded3d8c2be96e61d56f933feef9e1f", - "sha256:561be4e3e952c2f9056fba5267b99be4ec2afadc27261505d4992c50b33c513c", - "sha256:601d3e42452cd4f2891c13fa8c70366d71851c1593ed42f57bf37f40f7dca3c8", - "sha256:644904600c15816a1f9a1bafa6aab0d21db2788abcdf4e2a77951280473f33e1", - "sha256:653a5dfd00f601a0ed6654a8b877b18d65ac32c9d9997456e0ab240807be6cf7", - "sha256:694a5e9f1f2c124a17ff2d0be613fd53ba0c26de588eb4bdab8bca855e550d95", - "sha256:71b4a48a7427f14679f0015b13c712863d28bb1ab700bd11776a5368135c7d60", - "sha256:72bf9308a82b75039b8c8edd2be2924c352eda5da14a920551a8b65d5ee89253", - "sha256:735dceec50fa907a3c314b84ed609dec54b76a814aa14eb90da31d1d36873a5e", - "sha256:73802194f10c394c2bedce7a135ba1d8ba6cff23adf4217612bfc5cf060de34c", - "sha256:780daad9e35b18d10d7219d24bfb30148ca2afc309928e1d4d53de86822593dc", - "sha256:8655f55fe68c4685673265a650ef71beb2d31871c049c8b80262026f23605ee3", - "sha256:877045a7969ace04d59516d5d6a7dee13106822f99a5d8df5e6822941f7bedc8", - "sha256:87bce04f09f0552b66fca0c4e10da78d17cb0e71c205864bab4e9595122cb9d9", - "sha256:8d4dfc66abea3ec6d9f83e837a8f8a7d9d3a76d25c9911735c76d6745950e62c", - "sha256:8ec364e280db4235389b5e1e6ee924723c693cbc98e9d28dc1767041ff9bc388", - "sha256:8fa00fa24ffd8c31fac081bf7be7eb495be6d248db127f8776575a746fa55c95", - "sha256:920c4897e55e2881db6a6da151198e5001552c3777cd42b8a4c2f72eedc2ee91", - "sha256:920f4633bee43d7a2818e1a1a788906df5a17b7ab6fe411220ed92b42940f818", - "sha256:9795f56aa6b2296f05ac79d8a424e94056730c0b860a62b0fdcfe6340b658cc8", - "sha256:98f0edee7ee9cc7f9221af2e1b95bd02810e1c7a6d115cfd82698803d385b28f", - "sha256:99c095457eea8550c9fa9a7a992e842aeae1429dab6b6b378710f62bfb70b394", - "sha256:99d3a433ef5dc3021c9534a58a3686c88363c591974c16c54a01af7efd741f13", - "sha256:99f9a50b56713a598d33bc23a9912224fc5d7f9f292444e6664236ae471ddf17", - "sha256:9c46e556ee266ed3fb7b7a882b53df3c76b45e872fdab8d9cf49ae5e91147fd7", - "sha256:9f5d37ff01edcbace53a402e80793640c25798fb7208f105d87a25e6fcc9ea06", - "sha256:a0b4cfe408cd84c53bab7d83e4209458de676a6ec5e9c623ae914ce1cb79b96f", - "sha256:a497be217818c318d93f07e14502ef93d44e6a20c72b04c530611e45e54c2196", - "sha256:ac89ccc39cd1d556cc72d6752f252dc869dde41c7c936e86beac5eb555041b66", - "sha256:adf28099d061a25fbcc6531febb7a091e027605385de9fe14dd6a97319d614cf", - "sha256:afa01d25769af33a8dac0d905d5c7bb2d73c7c3d5161b2dd6f8b5b5eea6a3c4c", - "sha256:b1fc07896fc1851558f532dffc8987e526b682ec73140886c831d773cef44b76", - "sha256:b49c604ace7a7aa8af31196abbf8f2193be605db6739ed905ecaf62af31ccae0", - "sha256:b9f3e0bffad6e238f7acc20c393c1ed8fab4371e3b3bc311020dfa6020d99212", - "sha256:ba07646f35e4e49376c9831130039d1b478fbfa1215ae62ad62d2ee63cf9c18f", - "sha256:bd88f40f2294440d3f3c6308e50d96a0d3d0973d6f1a5732875d10f569acef49", - "sha256:c0be58529d43d38ae849a91932391eb93275a06b93b79a8ab828b012e916a206", - "sha256:c45f62e4107ebd05166717ac58f6feb44471ed450d07fecd90e5f69d9bf03c48", - "sha256:c56da23034fe66221f2208c813d8aa509eea34d97328ce2add56e219c3a9f41c", - "sha256:c94b5537bf6ce66e4d7830c6993152940a188600f6ae044435287753044a8fe2", - "sha256:cebf8d56fee3b08ad40d332a807ecccd4153d3f1ba8231e111d9759f02edfd05", - "sha256:d0bf6f93a55d3fa7a079d811b29100b019784e2ee6bc06b0bb839538272a5610", - "sha256:d195add190abccefc70ad0f9a0141ad7da53e16183048380e688b466702195dd", - "sha256:d25ef0c33f22649b7a088035fd65ac1ce6464fa2876578df1adad9472f918a76", - "sha256:d6cbdf12ef967a6aa401cf5cdf47850559e59eedad10e781471c960583f25aa1", - "sha256:d8c032ccee90b37b44e05948b449a2d6baed7e614df3d3f47fe432c952c21b60", - "sha256:daff04257b49ab7f4b3f73f98283d3dbb1a65bf3500d55c7beac3c66c310fe34", - "sha256:e83ebbf020be727d6e0991c1b192a5c2e7113eb66e3def0cd0c62f9f266247e4", - "sha256:ed3025a8a7e5a59817b7494686d449ebfbe301f3e757b852c8d0d1961d6be864", - "sha256:f1936ef138bed2165dd8573aa65e3095ef7c2b6247faccd0e15186aabdda7f66", - "sha256:f5247a3d74355f8b1d780d0f3b32a23dd9f6d3ff43ef2037c6dcd249f35ecf4c", - "sha256:fa496cd45cda0165d597e9d6f01e36c33c9508f75cf03c0a650018c5048f578e", - "sha256:fb4363e6c9fc87365c2bc777a1f585a22f2f56642501885ffc7942138499bf54", - "sha256:fb4370b15111905bf8b5ba2129b926af9470f014cb0493a67d23e9d7a48348e8", - "sha256:fbec2af0ebafa57eb82c18c304b37c86a8abddf7022955d1742b3d5471a6339e" + "sha256:02906e7306cb8c5901a1feb61f9ab5e5c690dbbeaa04d84c1b9ae2a01ebe9379", + "sha256:0ba503850d8b8dcc18391f10de896ae51d37fe5fe43dbfb6a35c5c5cad271a06", + "sha256:16aa02e7a0f539098e215fc193c8926c897175d64c7926d00a36188917717a05", + "sha256:18de31781cdc7e7b28678df7c2d7882f9692ad060bc6ee3c94eb15a5d733f8f7", + "sha256:22c5f022799f3cd6741e24f0443ead92ef42be93ffda0d29b2597208c94c3753", + "sha256:2924b89b16420712e9bb8192396026a8fbd6d8726224f918353ac19c4c043d2a", + "sha256:308974fdf98046db28440eb3377abba274808bf66262e042c412eb2adf852731", + "sha256:396fdf88b1b503c9c59c84a08b6833ec0c3b5ad1a83230252a9e17b7dfb4cffc", + "sha256:3ac426704840877a285d03a445e162eb258924f014e2f074e209d9b4ff7bf380", + "sha256:3b052c753c4babf2d1edc034c97851f867c87d6f3ea63a12e2700f159f5c41c3", + "sha256:3fab4e75b8c525a4776e7630b9ee48aea50107fea6ca9f593c98da3f4d11bf7c", + "sha256:406fac1d09edc613020ce9cf3f2ccf1a1b2f57ab00552b4c18e3d5276c67eb11", + "sha256:40a0bd0bed96dae5712dab2aba7d334a6c67cbcac2ddfca7dbcc4a8176445990", + "sha256:41dac3b9fce187a25c6253ec79a3f9e2a7e761eb08690e90415069ea4a68ff7a", + "sha256:459c0d338cc55d099798618f714b21b7ece17eb1a87879f2da20a3ff4c7628e2", + "sha256:459d6be6134ce3b38e0ef76f8a672924460c455d45f1ad8fdade36796df1ddc8", + "sha256:46b0d5520dbcafea9a8645a8164658777686c5c524d381d983317d29687cce97", + "sha256:47924039e785a04d4a4fa49455e51b4eb3422d6eaacfde9fc9abf8fdef164e8a", + "sha256:4bfcbde6e06c56b30668a0c872d75a7ef3025dc3c1823a13cf29a0e9b33f67e8", + "sha256:4f9ee4febb249c591d07b2d4dd36ebcad0ccd128962aaa1801508320896575ef", + "sha256:55749f745ebf154c0d63d46c8c58594d8894b161928aa41adbb0709c1fe78b77", + "sha256:5864b0242f74b9dd0b78fd39db1768bc3f00d1ffc14e596fd3e3f2ce43436a33", + "sha256:5f60f920691a620b03082692c378661947d09415743e437a7478c309eb0e4f82", + "sha256:60eb8ceaa40a41540b9acae6ae7c1f0a67d233c40dc4359c256ad2ad85bdf5e5", + "sha256:69a7b96b59322a81c2203be537957313b07dd333105b73db0b69212c7d867b4b", + "sha256:6ad84731a26bcfb299f9eab56c7932d46f9cad51c52768cace09e92a19e4cf55", + "sha256:6db58c22ac6c81aeac33912fb1af0e930bc9774166cdd56eade913d5f2fff35e", + "sha256:70651ff6e663428cea902dac297066d5c6e5423fda345a4ca62430575364d62b", + "sha256:72f7919af5de5ecfaf1eba47bf9a5d8aa089a3340277276e5636d16ee97614d7", + "sha256:732bd062c9e5d9582a30e8751461c1917dd1ccbdd6cafb032f02c86b20d2e7ec", + "sha256:7924e54f7ce5d253d6160090ddc6df25ed2feea25bfb3339b424a9dd591688bc", + "sha256:7afb844041e707ac9ad9acad2188a90bffce2c770e6dc2318be0c9916aef1469", + "sha256:7b883af50eaa6bb3299780651e5be921e88050ccf00e3e583b1e92020333304b", + "sha256:7beec26729d496a12fd23cf8da9944ee338c8b8a17035a560b585c36fe81af20", + "sha256:7bf26c2e2ea59d32807081ad51968133af3025c4ba5753e6a794683d2c91bf6e", + "sha256:7c31669e0c8cc68400ef0c730c3a1e11317ba76b892deeefaf52dcb41d56ed5d", + "sha256:7e6231aa5bdacda78e96ad7b07d0c312f34ba35d717115f4b4bff6cb87224f0f", + "sha256:870dbfa94de9b8866b37b867a2cb37a60c401d9deb4a9ea392abf11a1f98037b", + "sha256:88646cae28eb1dd5cd1e09605680c2b043b64d7481cdad7f5003ebef401a3039", + "sha256:8aafeedb6597a163a9c9727d8a8bd363a93277701b7bfd2749fbefee2396469e", + "sha256:8bde5b48c65b8e807409e6f20baee5d2cd880e0fad00b1a811ebc43e39a00ab2", + "sha256:8f9142a6ed83d90c94a3efd7af8873bf7cefed2d3d44387bf848888482e2d25f", + "sha256:936a787f83db1f2115ee829dd615c4f684ee48ac4de5779ab4300994d8af325b", + "sha256:98dc6f4f2095fc7ad277782a7c2c88296badcad92316b5a6e530930b1d475ebc", + "sha256:9957433c3a1b67bdd4c63717eaf174ebb749510d5ea612cd4e83f2d9142f3fc8", + "sha256:99af961d72ac731aae2a1b55ccbdae0733d816f8bfb97b41909e143de735f522", + "sha256:9b5f13857da99325dcabe1cc4e9e6a3d7b2e2c726248ba5dd4be3e8e4a0b6d0e", + "sha256:9d776d30cde7e541b8180103c3f294ef7c1862fd45d81738d156d00551005784", + "sha256:9da90d393a8227d717c19f5397688a38635afec89f2e2d7af0df037f3249c39a", + "sha256:a3b7352b48fbc8b446b75f3069124e87f599d25afb8baa96a550256c031bb890", + "sha256:a477932664d9611d7a0816cc3c0eb1f8856f8a42435488280dfbf4395e141485", + "sha256:a7e41e3ada4cca5f22b478c08e973c930e5e6c7ba3588fb8e35f2398cdcc1545", + "sha256:a90fec23b4b05a09ad988e7a4f4e081711a90eb2a55b9c984d8b74597599180f", + "sha256:a9e523474998fb33f7c1a4d55f5504c908d57add624599e095c20fa575b8d943", + "sha256:aa057095f621dad24a1e906747179a69780ef45cc8f69e97463692adbcdae878", + "sha256:aa6c8c582036275997a733427b88031a32ffa5dfc3124dc25a730658c47a572f", + "sha256:ae34418b6b389d601b31153b84dce480351a352e0bb763684a1b993d6be30f17", + "sha256:b0d7a9165167269758145756db43a133608a531b1e5bb6a626b9ee24bc38a8f7", + "sha256:b30b0dd58a4509c3bd7eefddf6338565c4905406aee0c6e4a5293841411a1286", + "sha256:b8f9186ca45aee030dc8234118b9c0784ad91a0bb27fc4e7d9d6608a5e3d386c", + "sha256:b94cbda27267423411c928208e89adddf2ea5dd5f74b9528513f0358bba019cb", + "sha256:cc6f6c9be0ab6da37bc77c2dda5f14b1d532d5dbef00311ee6e13357a418e646", + "sha256:ce232a6170dd6532096cadbf6185271e4e8c70fc9217ebe105923ac105da9978", + "sha256:cf903310a34e14651c9de056fcc12ce090560864d5a2bb0174b971685684e1d8", + "sha256:d5362d099c244a2d2f9659fb3c9db7c735f0004765bbe06b99be69fbd87c3f15", + "sha256:dffaf740fe2e147fedcb6b561353a16243e654f7fe8e701b1b9db148242e1272", + "sha256:e0f686549e32ccdb02ae6f25eee40cc33900910085de6aa3790effd391ae10c2", + "sha256:e4b52776a2e3230f4854907a1e0946eec04d41b1fc64069ee774876bbe0eab55", + "sha256:e4ba0884a91f1aecce75202473ab138724aa4fb26d7707f2e1fa6c3e68c84fbf", + "sha256:e6294e76b0380bb7a61eb8a39273c40b20beb35e8c87ee101062834ced19c545", + "sha256:ebb892ed8599b23fa8f1799e13a12c87a97a6c9d0f497525ce9858564c4575a4", + "sha256:eca58e319f4fd6df004762419612122b2c7e7d95ffafc37e890252f869f3fb2a", + "sha256:ed957db4c33bc99895f3a1672eca7e80e8cda8bd1e29a80536b4ec2153fa9804", + "sha256:ef551c053692b1e39e3f7950ce2296536728871110e7d75c4e7753fb30ca87f4", + "sha256:ef6113cd31411eaf9b39fc5a8848e71c72656fd418882488598758b2c8c6dfa0", + "sha256:f685dbc1fdadb1dcd5b5e51e0a378d4685a891b2ddaf8e2bba89bd3a7144e44a", + "sha256:f8ed79883b4328b7f0bd142733d99c8e6b22703e908ec63d930b06be3a0e7113", + "sha256:fe56851c3f1d6f5384b3051c536cc81b3a93a73faf931f404fef95217cf1e10d", + "sha256:ff7c97eb7a29aba230389a2661edf2e9e06ce616c7e35aa764879b6894a44b25" ], "markers": "python_version >= '3.8'", - "version": "==2.16.1" + "version": "==2.16.2" }, "pypdf2": { "hashes": [ @@ -1358,10 +1374,10 @@ }, "pytz": { "hashes": [ - "sha256:31d4583c4ed539cd037956140d695e42c033a19e984bfce9964a3f7d59bc2b40", - "sha256:f90ef520d95e7c46951105338d918664ebfd6f1d995bd7d153127ce90efafa6a" + "sha256:2a29735ea9c18baf14b448846bde5a48030ed267578472d8955cd0e7443a9812", + "sha256:328171f4e3623139da4983451950b28e95ac706e13f3f2630a879749e7a8b319" ], - "version": "==2023.4" + "version": "==2024.1" }, "pyyaml": { "hashes": [ @@ -1547,108 +1563,108 @@ }, "rpds-py": { "hashes": [ - "sha256:01f58a7306b64e0a4fe042047dd2b7d411ee82e54240284bab63e325762c1147", - "sha256:0210b2668f24c078307260bf88bdac9d6f1093635df5123789bfee4d8d7fc8e7", - "sha256:02866e060219514940342a1f84303a1ef7a1dad0ac311792fbbe19b521b489d2", - "sha256:0387ce69ba06e43df54e43968090f3626e231e4bc9150e4c3246947567695f68", - "sha256:060f412230d5f19fc8c8b75f315931b408d8ebf56aec33ef4168d1b9e54200b1", - "sha256:071bc28c589b86bc6351a339114fb7a029f5cddbaca34103aa573eba7b482382", - "sha256:0bfb09bf41fe7c51413f563373e5f537eaa653d7adc4830399d4e9bdc199959d", - "sha256:10162fe3f5f47c37ebf6d8ff5a2368508fe22007e3077bf25b9c7d803454d921", - "sha256:149c5cd24f729e3567b56e1795f74577aa3126c14c11e457bec1b1c90d212e38", - "sha256:1701fc54460ae2e5efc1dd6350eafd7a760f516df8dbe51d4a1c79d69472fbd4", - "sha256:1957a2ab607f9added64478a6982742eb29f109d89d065fa44e01691a20fc20a", - "sha256:1a746a6d49665058a5896000e8d9d2f1a6acba8a03b389c1e4c06e11e0b7f40d", - "sha256:1bfcad3109c1e5ba3cbe2f421614e70439f72897515a96c462ea657261b96518", - "sha256:1d36b2b59e8cc6e576f8f7b671e32f2ff43153f0ad6d0201250a7c07f25d570e", - "sha256:1db228102ab9d1ff4c64148c96320d0be7044fa28bd865a9ce628ce98da5973d", - "sha256:1dc29db3900cb1bb40353772417800f29c3d078dbc8024fd64655a04ee3c4bdf", - "sha256:1e626b365293a2142a62b9a614e1f8e331b28f3ca57b9f05ebbf4cf2a0f0bdc5", - "sha256:1f3c3461ebb4c4f1bbc70b15d20b565759f97a5aaf13af811fcefc892e9197ba", - "sha256:20de7b7179e2031a04042e85dc463a93a82bc177eeba5ddd13ff746325558aa6", - "sha256:24e4900a6643f87058a27320f81336d527ccfe503984528edde4bb660c8c8d59", - "sha256:2528ff96d09f12e638695f3a2e0c609c7b84c6df7c5ae9bfeb9252b6fa686253", - "sha256:25f071737dae674ca8937a73d0f43f5a52e92c2d178330b4c0bb6ab05586ffa6", - "sha256:270987bc22e7e5a962b1094953ae901395e8c1e1e83ad016c5cfcfff75a15a3f", - "sha256:292f7344a3301802e7c25c53792fae7d1593cb0e50964e7bcdcc5cf533d634e3", - "sha256:2953937f83820376b5979318840f3ee47477d94c17b940fe31d9458d79ae7eea", - "sha256:2a792b2e1d3038daa83fa474d559acfd6dc1e3650ee93b2662ddc17dbff20ad1", - "sha256:2a7b2f2f56a16a6d62e55354dd329d929560442bd92e87397b7a9586a32e3e76", - "sha256:2f4eb548daf4836e3b2c662033bfbfc551db58d30fd8fe660314f86bf8510b93", - "sha256:3664d126d3388a887db44c2e293f87d500c4184ec43d5d14d2d2babdb4c64cad", - "sha256:3677fcca7fb728c86a78660c7fb1b07b69b281964673f486ae72860e13f512ad", - "sha256:380e0df2e9d5d5d339803cfc6d183a5442ad7ab3c63c2a0982e8c824566c5ccc", - "sha256:3ac732390d529d8469b831949c78085b034bff67f584559340008d0f6041a049", - "sha256:4128980a14ed805e1b91a7ed551250282a8ddf8201a4e9f8f5b7e6225f54170d", - "sha256:4341bd7579611cf50e7b20bb8c2e23512a3dc79de987a1f411cb458ab670eb90", - "sha256:436474f17733c7dca0fbf096d36ae65277e8645039df12a0fa52445ca494729d", - "sha256:4dc889a9d8a34758d0fcc9ac86adb97bab3fb7f0c4d29794357eb147536483fd", - "sha256:4e21b76075c01d65d0f0f34302b5a7457d95721d5e0667aea65e5bb3ab415c25", - "sha256:516fb8c77805159e97a689e2f1c80655c7658f5af601c34ffdb916605598cda2", - "sha256:5576ee2f3a309d2bb403ec292d5958ce03953b0e57a11d224c1f134feaf8c40f", - "sha256:5a024fa96d541fd7edaa0e9d904601c6445e95a729a2900c5aec6555fe921ed6", - "sha256:5d0e8a6434a3fbf77d11448c9c25b2f25244226cfbec1a5159947cac5b8c5fa4", - "sha256:5e7d63ec01fe7c76c2dbb7e972fece45acbb8836e72682bde138e7e039906e2c", - "sha256:60e820ee1004327609b28db8307acc27f5f2e9a0b185b2064c5f23e815f248f8", - "sha256:637b802f3f069a64436d432117a7e58fab414b4e27a7e81049817ae94de45d8d", - "sha256:65dcf105c1943cba45d19207ef51b8bc46d232a381e94dd38719d52d3980015b", - "sha256:698ea95a60c8b16b58be9d854c9f993c639f5c214cf9ba782eca53a8789d6b19", - "sha256:70fcc6c2906cfa5c6a552ba7ae2ce64b6c32f437d8f3f8eea49925b278a61453", - "sha256:720215373a280f78a1814becb1312d4e4d1077b1202a56d2b0815e95ccb99ce9", - "sha256:7450dbd659fed6dd41d1a7d47ed767e893ba402af8ae664c157c255ec6067fde", - "sha256:7b7d9ca34542099b4e185b3c2a2b2eda2e318a7dbde0b0d83357a6d4421b5296", - "sha256:7fbd70cb8b54fe745301921b0816c08b6d917593429dfc437fd024b5ba713c58", - "sha256:81038ff87a4e04c22e1d81f947c6ac46f122e0c80460b9006e6517c4d842a6ec", - "sha256:810685321f4a304b2b55577c915bece4c4a06dfe38f6e62d9cc1d6ca8ee86b99", - "sha256:82ada4a8ed9e82e443fcef87e22a3eed3654dd3adf6e3b3a0deb70f03e86142a", - "sha256:841320e1841bb53fada91c9725e766bb25009cfd4144e92298db296fb6c894fb", - "sha256:8587fd64c2a91c33cdc39d0cebdaf30e79491cc029a37fcd458ba863f8815383", - "sha256:8ffe53e1d8ef2520ebcf0c9fec15bb721da59e8ef283b6ff3079613b1e30513d", - "sha256:9051e3d2af8f55b42061603e29e744724cb5f65b128a491446cc029b3e2ea896", - "sha256:91e5a8200e65aaac342a791272c564dffcf1281abd635d304d6c4e6b495f29dc", - "sha256:93432e747fb07fa567ad9cc7aaadd6e29710e515aabf939dfbed8046041346c6", - "sha256:938eab7323a736533f015e6069a7d53ef2dcc841e4e533b782c2bfb9fb12d84b", - "sha256:9584f8f52010295a4a417221861df9bea4c72d9632562b6e59b3c7b87a1522b7", - "sha256:9737bdaa0ad33d34c0efc718741abaafce62fadae72c8b251df9b0c823c63b22", - "sha256:99da0a4686ada4ed0f778120a0ea8d066de1a0a92ab0d13ae68492a437db78bf", - "sha256:99f567dae93e10be2daaa896e07513dd4bf9c2ecf0576e0533ac36ba3b1d5394", - "sha256:9bdf1303df671179eaf2cb41e8515a07fc78d9d00f111eadbe3e14262f59c3d0", - "sha256:9f0e4dc0f17dcea4ab9d13ac5c666b6b5337042b4d8f27e01b70fae41dd65c57", - "sha256:a000133a90eea274a6f28adc3084643263b1e7c1a5a66eb0a0a7a36aa757ed74", - "sha256:a3264e3e858de4fc601741498215835ff324ff2482fd4e4af61b46512dd7fc83", - "sha256:a71169d505af63bb4d20d23a8fbd4c6ce272e7bce6cc31f617152aa784436f29", - "sha256:a967dd6afda7715d911c25a6ba1517975acd8d1092b2f326718725461a3d33f9", - "sha256:aa5bfb13f1e89151ade0eb812f7b0d7a4d643406caaad65ce1cbabe0a66d695f", - "sha256:ae35e8e6801c5ab071b992cb2da958eee76340e6926ec693b5ff7d6381441745", - "sha256:b686f25377f9c006acbac63f61614416a6317133ab7fafe5de5f7dc8a06d42eb", - "sha256:b760a56e080a826c2e5af09002c1a037382ed21d03134eb6294812dda268c811", - "sha256:b86b21b348f7e5485fae740d845c65a880f5d1eda1e063bc59bef92d1f7d0c55", - "sha256:b9412abdf0ba70faa6e2ee6c0cc62a8defb772e78860cef419865917d86c7342", - "sha256:bd345a13ce06e94c753dab52f8e71e5252aec1e4f8022d24d56decd31e1b9b23", - "sha256:be22ae34d68544df293152b7e50895ba70d2a833ad9566932d750d3625918b82", - "sha256:bf046179d011e6114daf12a534d874958b039342b347348a78b7cdf0dd9d6041", - "sha256:c3d2010656999b63e628a3c694f23020322b4178c450dc478558a2b6ef3cb9bb", - "sha256:c64602e8be701c6cfe42064b71c84ce62ce66ddc6422c15463fd8127db3d8066", - "sha256:d65e6b4f1443048eb7e833c2accb4fa7ee67cc7d54f31b4f0555b474758bee55", - "sha256:d8bbd8e56f3ba25a7d0cf980fc42b34028848a53a0e36c9918550e0280b9d0b6", - "sha256:da1ead63368c04a9bded7904757dfcae01eba0e0f9bc41d3d7f57ebf1c04015a", - "sha256:dbbb95e6fc91ea3102505d111b327004d1c4ce98d56a4a02e82cd451f9f57140", - "sha256:dbc56680ecf585a384fbd93cd42bc82668b77cb525343170a2d86dafaed2a84b", - "sha256:df3b6f45ba4515632c5064e35ca7f31d51d13d1479673185ba8f9fefbbed58b9", - "sha256:dfe07308b311a8293a0d5ef4e61411c5c20f682db6b5e73de6c7c8824272c256", - "sha256:e796051f2070f47230c745d0a77a91088fbee2cc0502e9b796b9c6471983718c", - "sha256:efa767c220d94aa4ac3a6dd3aeb986e9f229eaf5bce92d8b1b3018d06bed3772", - "sha256:f0b8bf5b8db49d8fd40f54772a1dcf262e8be0ad2ab0206b5a2ec109c176c0a4", - "sha256:f175e95a197f6a4059b50757a3dca33b32b61691bdbd22c29e8a8d21d3914cae", - "sha256:f2f3b28b40fddcb6c1f1f6c88c6f3769cd933fa493ceb79da45968a21dccc920", - "sha256:f6c43b6f97209e370124baf2bf40bb1e8edc25311a158867eb1c3a5d449ebc7a", - "sha256:f7f4cb1f173385e8a39c29510dd11a78bf44e360fb75610594973f5ea141028b", - "sha256:fad059a4bd14c45776600d223ec194e77db6c20255578bb5bcdd7c18fd169361", - "sha256:ff1dcb8e8bc2261a088821b2595ef031c91d499a0c1b031c152d43fe0a6ecec8", - "sha256:ffee088ea9b593cc6160518ba9bd319b5475e5f3e578e4552d63818773c6f56a" + "sha256:01e36a39af54a30f28b73096dd39b6802eddd04c90dbe161c1b8dbe22353189f", + "sha256:044a3e61a7c2dafacae99d1e722cc2d4c05280790ec5a05031b3876809d89a5c", + "sha256:08231ac30a842bd04daabc4d71fddd7e6d26189406d5a69535638e4dcb88fe76", + "sha256:08f9ad53c3f31dfb4baa00da22f1e862900f45908383c062c27628754af2e88e", + "sha256:0ab39c1ba9023914297dd88ec3b3b3c3f33671baeb6acf82ad7ce883f6e8e157", + "sha256:0af039631b6de0397ab2ba16eaf2872e9f8fca391b44d3d8cac317860a700a3f", + "sha256:0b8612cd233543a3781bc659c731b9d607de65890085098986dfd573fc2befe5", + "sha256:11a8c85ef4a07a7638180bf04fe189d12757c696eb41f310d2426895356dcf05", + "sha256:1374f4129f9bcca53a1bba0bb86bf78325a0374577cf7e9e4cd046b1e6f20e24", + "sha256:1d4acf42190d449d5e89654d5c1ed3a4f17925eec71f05e2a41414689cda02d1", + "sha256:1d9a5be316c15ffb2b3c405c4ff14448c36b4435be062a7f578ccd8b01f0c4d8", + "sha256:1df3659d26f539ac74fb3b0c481cdf9d725386e3552c6fa2974f4d33d78e544b", + "sha256:22806714311a69fd0af9b35b7be97c18a0fc2826e6827dbb3a8c94eac6cf7eeb", + "sha256:2644e47de560eb7bd55c20fc59f6daa04682655c58d08185a9b95c1970fa1e07", + "sha256:2e6d75ab12b0bbab7215e5d40f1e5b738aa539598db27ef83b2ec46747df90e1", + "sha256:30f43887bbae0d49113cbaab729a112251a940e9b274536613097ab8b4899cf6", + "sha256:34b18ba135c687f4dac449aa5157d36e2cbb7c03cbea4ddbd88604e076aa836e", + "sha256:36b3ee798c58ace201289024b52788161e1ea133e4ac93fba7d49da5fec0ef9e", + "sha256:39514da80f971362f9267c600b6d459bfbbc549cffc2cef8e47474fddc9b45b1", + "sha256:39f5441553f1c2aed4de4377178ad8ff8f9d733723d6c66d983d75341de265ab", + "sha256:3a96e0c6a41dcdba3a0a581bbf6c44bb863f27c541547fb4b9711fd8cf0ffad4", + "sha256:3f26b5bd1079acdb0c7a5645e350fe54d16b17bfc5e71f371c449383d3342e17", + "sha256:41ef53e7c58aa4ef281da975f62c258950f54b76ec8e45941e93a3d1d8580594", + "sha256:42821446ee7a76f5d9f71f9e33a4fb2ffd724bb3e7f93386150b61a43115788d", + "sha256:43fbac5f22e25bee1d482c97474f930a353542855f05c1161fd804c9dc74a09d", + "sha256:4457a94da0d5c53dc4b3e4de1158bdab077db23c53232f37a3cb7afdb053a4e3", + "sha256:465a3eb5659338cf2a9243e50ad9b2296fa15061736d6e26240e713522b6235c", + "sha256:482103aed1dfe2f3b71a58eff35ba105289b8d862551ea576bd15479aba01f66", + "sha256:4832d7d380477521a8c1644bbab6588dfedea5e30a7d967b5fb75977c45fd77f", + "sha256:4901165d170a5fde6f589acb90a6b33629ad1ec976d4529e769c6f3d885e3e80", + "sha256:5307def11a35f5ae4581a0b658b0af8178c65c530e94893345bebf41cc139d33", + "sha256:5417558f6887e9b6b65b4527232553c139b57ec42c64570569b155262ac0754f", + "sha256:56a737287efecafc16f6d067c2ea0117abadcd078d58721f967952db329a3e5c", + "sha256:586f8204935b9ec884500498ccc91aa869fc652c40c093bd9e1471fbcc25c022", + "sha256:5b4e7d8d6c9b2e8ee2d55c90b59c707ca59bc30058269b3db7b1f8df5763557e", + "sha256:5ddcba87675b6d509139d1b521e0c8250e967e63b5909a7e8f8944d0f90ff36f", + "sha256:618a3d6cae6ef8ec88bb76dd80b83cfe415ad4f1d942ca2a903bf6b6ff97a2da", + "sha256:635dc434ff724b178cb192c70016cc0ad25a275228f749ee0daf0eddbc8183b1", + "sha256:661d25cbffaf8cc42e971dd570d87cb29a665f49f4abe1f9e76be9a5182c4688", + "sha256:66e6a3af5a75363d2c9a48b07cb27c4ea542938b1a2e93b15a503cdfa8490795", + "sha256:67071a6171e92b6da534b8ae326505f7c18022c6f19072a81dcf40db2638767c", + "sha256:685537e07897f173abcf67258bee3c05c374fa6fff89d4c7e42fb391b0605e98", + "sha256:69e64831e22a6b377772e7fb337533c365085b31619005802a79242fee620bc1", + "sha256:6b0817e34942b2ca527b0e9298373e7cc75f429e8da2055607f4931fded23e20", + "sha256:6c81e5f372cd0dc5dc4809553d34f832f60a46034a5f187756d9b90586c2c307", + "sha256:6d7faa6f14017c0b1e69f5e2c357b998731ea75a442ab3841c0dbbbfe902d2c4", + "sha256:6ef0befbb5d79cf32d0266f5cff01545602344eda89480e1dd88aca964260b18", + "sha256:6ef687afab047554a2d366e112dd187b62d261d49eb79b77e386f94644363294", + "sha256:7223a2a5fe0d217e60a60cdae28d6949140dde9c3bcc714063c5b463065e3d66", + "sha256:77f195baa60a54ef9d2de16fbbfd3ff8b04edc0c0140a761b56c267ac11aa467", + "sha256:793968759cd0d96cac1e367afd70c235867831983f876a53389ad869b043c948", + "sha256:7bd339195d84439cbe5771546fe8a4e8a7a045417d8f9de9a368c434e42a721e", + "sha256:7cd863afe7336c62ec78d7d1349a2f34c007a3cc6c2369d667c65aeec412a5b1", + "sha256:7f2facbd386dd60cbbf1a794181e6aa0bd429bd78bfdf775436020172e2a23f0", + "sha256:84ffab12db93b5f6bad84c712c92060a2d321b35c3c9960b43d08d0f639d60d7", + "sha256:8c8370641f1a7f0e0669ddccca22f1da893cef7628396431eb445d46d893e5cd", + "sha256:8db715ebe3bb7d86d77ac1826f7d67ec11a70dbd2376b7cc214199360517b641", + "sha256:8e8916ae4c720529e18afa0b879473049e95949bf97042e938530e072fde061d", + "sha256:8f03bccbd8586e9dd37219bce4d4e0d3ab492e6b3b533e973fa08a112cb2ffc9", + "sha256:8f2fc11e8fe034ee3c34d316d0ad8808f45bc3b9ce5857ff29d513f3ff2923a1", + "sha256:923d39efa3cfb7279a0327e337a7958bff00cc447fd07a25cddb0a1cc9a6d2da", + "sha256:93df1de2f7f7239dc9cc5a4a12408ee1598725036bd2dedadc14d94525192fc3", + "sha256:998e33ad22dc7ec7e030b3df701c43630b5bc0d8fbc2267653577e3fec279afa", + "sha256:99f70b740dc04d09e6b2699b675874367885217a2e9f782bdf5395632ac663b7", + "sha256:9a00312dea9310d4cb7dbd7787e722d2e86a95c2db92fbd7d0155f97127bcb40", + "sha256:9d54553c1136b50fd12cc17e5b11ad07374c316df307e4cfd6441bea5fb68496", + "sha256:9dbbeb27f4e70bfd9eec1be5477517365afe05a9b2c441a0b21929ee61048124", + "sha256:a1ce3ba137ed54f83e56fb983a5859a27d43a40188ba798993812fed73c70836", + "sha256:a34d557a42aa28bd5c48a023c570219ba2593bcbbb8dc1b98d8cf5d529ab1434", + "sha256:a5f446dd5055667aabaee78487f2b5ab72e244f9bc0b2ffebfeec79051679984", + "sha256:ad36cfb355e24f1bd37cac88c112cd7730873f20fb0bdaf8ba59eedf8216079f", + "sha256:aec493917dd45e3c69d00a8874e7cbed844efd935595ef78a0f25f14312e33c6", + "sha256:b316144e85316da2723f9d8dc75bada12fa58489a527091fa1d5a612643d1a0e", + "sha256:b34ae4636dfc4e76a438ab826a0d1eed2589ca7d9a1b2d5bb546978ac6485461", + "sha256:b34b7aa8b261c1dbf7720b5d6f01f38243e9b9daf7e6b8bc1fd4657000062f2c", + "sha256:bc362ee4e314870a70f4ae88772d72d877246537d9f8cb8f7eacf10884862432", + "sha256:bed88b9a458e354014d662d47e7a5baafd7ff81c780fd91584a10d6ec842cb73", + "sha256:c0013fe6b46aa496a6749c77e00a3eb07952832ad6166bd481c74bda0dcb6d58", + "sha256:c0b5dcf9193625afd8ecc92312d6ed78781c46ecbf39af9ad4681fc9f464af88", + "sha256:c4325ff0442a12113a6379af66978c3fe562f846763287ef66bdc1d57925d337", + "sha256:c463ed05f9dfb9baebef68048aed8dcdc94411e4bf3d33a39ba97e271624f8f7", + "sha256:c8362467a0fdeccd47935f22c256bec5e6abe543bf0d66e3d3d57a8fb5731863", + "sha256:cd5bf1af8efe569654bbef5a3e0a56eca45f87cfcffab31dd8dde70da5982475", + "sha256:cf1ea2e34868f6fbf070e1af291c8180480310173de0b0c43fc38a02929fc0e3", + "sha256:d62dec4976954a23d7f91f2f4530852b0c7608116c257833922a896101336c51", + "sha256:d68c93e381010662ab873fea609bf6c0f428b6d0bb00f2c6939782e0818d37bf", + "sha256:d7c36232a90d4755b720fbd76739d8891732b18cf240a9c645d75f00639a9024", + "sha256:dd18772815d5f008fa03d2b9a681ae38d5ae9f0e599f7dda233c439fcaa00d40", + "sha256:ddc2f4dfd396c7bfa18e6ce371cba60e4cf9d2e5cdb71376aa2da264605b60b9", + "sha256:e003b002ec72c8d5a3e3da2989c7d6065b47d9eaa70cd8808b5384fbb970f4ec", + "sha256:e32a92116d4f2a80b629778280103d2a510a5b3f6314ceccd6e38006b5e92dcb", + "sha256:e4461d0f003a0aa9be2bdd1b798a041f177189c1a0f7619fe8c95ad08d9a45d7", + "sha256:e541ec6f2ec456934fd279a3120f856cd0aedd209fc3852eca563f81738f6861", + "sha256:e546e768d08ad55b20b11dbb78a745151acbd938f8f00d0cfbabe8b0199b9880", + "sha256:ea7d4a99f3b38c37eac212dbd6ec42b7a5ec51e2c74b5d3223e43c811609e65f", + "sha256:ed4eb745efbff0a8e9587d22a84be94a5eb7d2d99c02dacf7bd0911713ed14dd", + "sha256:f8a2f084546cc59ea99fda8e070be2fd140c3092dc11524a71aa8f0f3d5a55ca", + "sha256:fcb25daa9219b4cf3a0ab24b0eb9a5cc8949ed4dc72acb8fa16b7e1681aa3c58", + "sha256:fdea4952db2793c4ad0bdccd27c1d8fdd1423a92f04598bc39425bcc2b8ee46e" ], "markers": "python_version >= '3.8'", - "version": "==0.17.1" + "version": "==0.18.0" }, "rsa": { "hashes": [ @@ -1700,58 +1716,58 @@ }, "sqlalchemy": { "hashes": [ - "sha256:0d3cab3076af2e4aa5693f89622bef7fa770c6fec967143e4da7508b3dceb9b9", - "sha256:0dacf67aee53b16f365c589ce72e766efaabd2b145f9de7c917777b575e3659d", - "sha256:10331f129982a19df4284ceac6fe87353ca3ca6b4ca77ff7d697209ae0a5915e", - "sha256:14a6f68e8fc96e5e8f5647ef6cda6250c780612a573d99e4d881581432ef1669", - "sha256:1b1180cda6df7af84fe72e4530f192231b1f29a7496951db4ff38dac1687202d", - "sha256:29049e2c299b5ace92cbed0c1610a7a236f3baf4c6b66eb9547c01179f638ec5", - "sha256:342d365988ba88ada8af320d43df4e0b13a694dbd75951f537b2d5e4cb5cd002", - "sha256:420362338681eec03f53467804541a854617faed7272fe71a1bfdb07336a381e", - "sha256:4344d059265cc8b1b1be351bfb88749294b87a8b2bbe21dfbe066c4199541ebd", - "sha256:4f7a7d7fcc675d3d85fbf3b3828ecd5990b8d61bd6de3f1b260080b3beccf215", - "sha256:555651adbb503ac7f4cb35834c5e4ae0819aab2cd24857a123370764dc7d7e24", - "sha256:59a21853f5daeb50412d459cfb13cb82c089ad4c04ec208cd14dddd99fc23b39", - "sha256:5fdd402169aa00df3142149940b3bf9ce7dde075928c1886d9a1df63d4b8de62", - "sha256:605b6b059f4b57b277f75ace81cc5bc6335efcbcc4ccb9066695e515dbdb3900", - "sha256:665f0a3954635b5b777a55111ababf44b4fc12b1f3ba0a435b602b6387ffd7cf", - "sha256:6f9e2e59cbcc6ba1488404aad43de005d05ca56e069477b33ff74e91b6319735", - "sha256:736ea78cd06de6c21ecba7416499e7236a22374561493b456a1f7ffbe3f6cdb4", - "sha256:74b080c897563f81062b74e44f5a72fa44c2b373741a9ade701d5f789a10ba23", - "sha256:75432b5b14dc2fff43c50435e248b45c7cdadef73388e5610852b95280ffd0e9", - "sha256:75f99202324383d613ddd1f7455ac908dca9c2dd729ec8584c9541dd41822a2c", - "sha256:790f533fa5c8901a62b6fef5811d48980adeb2f51f1290ade8b5e7ba990ba3de", - "sha256:798f717ae7c806d67145f6ae94dc7c342d3222d3b9a311a784f371a4333212c7", - "sha256:7c88f0c7dcc5f99bdb34b4fd9b69b93c89f893f454f40219fe923a3a2fd11625", - "sha256:7d505815ac340568fd03f719446a589162d55c52f08abd77ba8964fbb7eb5b5f", - "sha256:84daa0a2055df9ca0f148a64fdde12ac635e30edbca80e87df9b3aaf419e144a", - "sha256:87d91043ea0dc65ee583026cb18e1b458d8ec5fc0a93637126b5fc0bc3ea68c4", - "sha256:87f6e732bccd7dcf1741c00f1ecf33797383128bd1c90144ac8adc02cbb98643", - "sha256:884272dcd3ad97f47702965a0e902b540541890f468d24bd1d98bcfe41c3f018", - "sha256:8b8cb63d3ea63b29074dcd29da4dc6a97ad1349151f2d2949495418fd6e48db9", - "sha256:91f7d9d1c4dd1f4f6e092874c128c11165eafcf7c963128f79e28f8445de82d5", - "sha256:a2c69a7664fb2d54b8682dd774c3b54f67f84fa123cf84dda2a5f40dcaa04e08", - "sha256:a3be4987e3ee9d9a380b66393b77a4cd6d742480c951a1c56a23c335caca4ce3", - "sha256:a86b4240e67d4753dc3092d9511886795b3c2852abe599cffe108952f7af7ac3", - "sha256:aa9373708763ef46782d10e950b49d0235bfe58facebd76917d3f5cbf5971aed", - "sha256:b64b183d610b424a160b0d4d880995e935208fc043d0302dd29fee32d1ee3f95", - "sha256:b801154027107461ee992ff4b5c09aa7cc6ec91ddfe50d02bca344918c3265c6", - "sha256:bb209a73b8307f8fe4fe46f6ad5979649be01607f11af1eb94aa9e8a3aaf77f0", - "sha256:bc8b7dabe8e67c4832891a5d322cec6d44ef02f432b4588390017f5cec186a84", - "sha256:c51db269513917394faec5e5c00d6f83829742ba62e2ac4fa5c98d58be91662f", - "sha256:c55731c116806836a5d678a70c84cb13f2cedba920212ba7dcad53260997666d", - "sha256:cf18ff7fc9941b8fc23437cc3e68ed4ebeff3599eec6ef5eebf305f3d2e9a7c2", - "sha256:d24f571990c05f6b36a396218f251f3e0dda916e0c687ef6fdca5072743208f5", - "sha256:db854730a25db7c956423bb9fb4bdd1216c839a689bf9cc15fada0a7fb2f4570", - "sha256:dc55990143cbd853a5d038c05e79284baedf3e299661389654551bd02a6a68d7", - "sha256:e607cdd99cbf9bb80391f54446b86e16eea6ad309361942bf88318bcd452363c", - "sha256:ecf6d4cda1f9f6cb0b45803a01ea7f034e2f1aed9475e883410812d9f9e3cfcf", - "sha256:f2a159111a0f58fb034c93eeba211b4141137ec4b0a6e75789ab7a3ef3c7e7e3", - "sha256:f37c0caf14b9e9b9e8f6dbc81bc56db06acb4363eba5a633167781a48ef036ed", - "sha256:f5693145220517b5f42393e07a6898acdfe820e136c98663b971906120549da5" + "sha256:03f448ffb731b48323bda68bcc93152f751436ad6037f18a42b7e16af9e91c07", + "sha256:0de1263aac858f288a80b2071990f02082c51d88335a1db0d589237a3435fe71", + "sha256:0fb3bffc0ced37e5aa4ac2416f56d6d858f46d4da70c09bb731a246e70bff4d5", + "sha256:120af1e49d614d2525ac247f6123841589b029c318b9afbfc9e2b70e22e1827d", + "sha256:1306102f6d9e625cebaca3d4c9c8f10588735ef877f0360b5cdb4fdfd3fd7131", + "sha256:15e19a84b84528f52a68143439d0c7a3a69befcd4f50b8ef9b7b69d2628ae7c4", + "sha256:1ab4e0448018d01b142c916cc7119ca573803a4745cfe341b8f95657812700ac", + "sha256:1fc19ae2e07a067663dd24fca55f8ed06a288384f0e6e3910420bf4b1270cc51", + "sha256:2f5c9dfb0b9ab5e3a8a00249534bdd838d943ec4cfb9abe176a6c33408430230", + "sha256:30d81cc1192dc693d49d5671cd40cdec596b885b0ce3b72f323888ab1c3863d5", + "sha256:33e8bde8fff203de50399b9039c4e14e42d4d227759155c21f8da4a47fc8053c", + "sha256:4535c49d961fe9a77392e3a630a626af5baa967172d42732b7a43496c8b28876", + "sha256:48217be1de7d29a5600b5c513f3f7664b21d32e596d69582be0a94e36b8309cb", + "sha256:5ada0438f5b74c3952d916c199367c29ee4d6858edff18eab783b3978d0db16d", + "sha256:5b78aa9f4f68212248aaf8943d84c0ff0f74efc65a661c2fc68b82d498311fd5", + "sha256:5cd20f58c29bbf2680039ff9f569fa6d21453fbd2fa84dbdb4092f006424c2e6", + "sha256:611068511b5531304137bcd7fe8117c985d1b828eb86043bd944cebb7fae3910", + "sha256:680b9a36029b30cf063698755d277885d4a0eab70a2c7c6e71aab601323cba45", + "sha256:6c5bad7c60a392850d2f0fee8f355953abaec878c483dd7c3836e0089f046bf6", + "sha256:6c7a596d0be71b7baa037f4ac10d5e057d276f65a9a611c46970f012752ebf2d", + "sha256:7f470327d06400a0aa7926b375b8e8c3c31d335e0884f509fe272b3c700a7254", + "sha256:86a6ed69a71fe6b88bf9331594fa390a2adda4a49b5c06f98e47bf0d392534f8", + "sha256:8dfc936870507da96aebb43e664ae3a71a7b96278382bcfe84d277b88e379b18", + "sha256:954d9735ee9c3fa74874c830d089a815b7b48df6f6b6e357a74130e478dbd951", + "sha256:9e56afce6431450442f3ab5973156289bd5ec33dd618941283847c9fd5ff06bf", + "sha256:a3012ab65ea42de1be81fff5fb28d6db893ef978950afc8130ba707179b4284a", + "sha256:ad862295ad3f644e3c2c0d8b10a988e1600d3123ecb48702d2c0f26771f1c396", + "sha256:b1d9d1bfd96eef3c3faedb73f486c89e44e64e40e5bfec304ee163de01cf996f", + "sha256:b86abba762ecfeea359112b2bb4490802b340850bbee1948f785141a5e020de8", + "sha256:b90053be91973a6fb6020a6e44382c97739736a5a9d74e08cc29b196639eb979", + "sha256:c4fbe6a766301f2e8a4519f4500fe74ef0a8509a59e07a4085458f26228cd7cc", + "sha256:ca891af9f3289d24a490a5fde664ea04fe2f4984cd97e26de7442a4251bd4b7c", + "sha256:cb0845e934647232b6ff5150df37ceffd0b67b754b9fdbb095233deebcddbd4a", + "sha256:ce850db091bf7d2a1f2fdb615220b968aeff3849007b1204bf6e3e50a57b3d32", + "sha256:d04e579e911562f1055d26dab1868d3e0bb905db3bccf664ee8ad109f035618a", + "sha256:d07ee7793f2aeb9b80ec8ceb96bc8cc08a2aec8a1b152da1955d64e4825fcbac", + "sha256:d177b7e82f6dd5e1aebd24d9c3297c70ce09cd1d5d37b43e53f39514379c029c", + "sha256:d7b5a3e2120982b8b6bd1d5d99e3025339f7fb8b8267551c679afb39e9c7c7f1", + "sha256:d873c21b356bfaf1589b89090a4011e6532582b3a8ea568a00e0c3aab09399dd", + "sha256:d997c5938a08b5e172c30583ba6b8aad657ed9901fc24caf3a7152eeccb2f1b4", + "sha256:dbcd77c4d94b23e0753c5ed8deba8c69f331d4fd83f68bfc9db58bc8983f49cd", + "sha256:e36aa62b765cf9f43a003233a8c2d7ffdeb55bc62eaa0a0380475b228663a38f", + "sha256:e97cf143d74a7a5a0f143aa34039b4fecf11343eed66538610debc438685db4a", + "sha256:eb15ef40b833f5b2f19eeae65d65e191f039e71790dd565c2af2a3783f72262f", + "sha256:ec1f5a328464daf7a1e4e385e4f5652dd9b1d12405075ccba1df842f7774b4fc", + "sha256:f9374e270e2553653d710ece397df67db9d19c60d2647bcd35bfc616f1622dcd", + "sha256:fa67d821c1fd268a5a87922ef4940442513b4e6c377553506b9db3b83beebbd8", + "sha256:fd8aafda7cdff03b905d4426b714601c0978725a19efc39f5f207b86d188ba01", + "sha256:ff2f1b7c963961d41403b650842dc2039175b906ab2093635d8319bef0b7d620" ], "markers": "python_version >= '3.7'", - "version": "==2.0.25" + "version": "==2.0.27" }, "sqlparse": { "hashes": [ @@ -1814,11 +1830,11 @@ }, "tqdm": { "hashes": [ - "sha256:d302b3c5b53d47bce91fea46679d9c3c6508cf6332229aa1e7d8653723793386", - "sha256:d88e651f9db8d8551a62556d3cff9e3034274ca5d66e93197cf2490e2dcb69c7" + "sha256:1ee4f8a893eb9bef51c6e35730cebf234d5d0b6bd112b0271e10ed7c24a02bd9", + "sha256:6cd52cdf0fef0e0f543299cfc96fec90d7b8a7e88745f411ec33eb44d5ed3531" ], "markers": "python_version >= '3.7'", - "version": "==4.66.1" + "version": "==4.66.2" }, "typing-extensions": { "hashes": [ @@ -1837,11 +1853,11 @@ }, "tzdata": { "hashes": [ - "sha256:aa3ace4329eeacda5b7beb7ea08ece826c28d761cda36e747cfbf97996d39bf3", - "sha256:dd54c94f294765522c77399649b4fefd95522479a664a0cec87f41bebc6148c9" + "sha256:2674120f8d891909751c38abcdfd386ac0a5a1127954fbc332af6b5ceae07efd", + "sha256:9068bc196136463f5245e51efda838afa15aaeca9903f49050dfa2679db4d252" ], "markers": "python_version >= '2'", - "version": "==2023.4" + "version": "==2024.1" }, "uritemplate": { "hashes": [ @@ -1856,7 +1872,7 @@ "sha256:c97dfde1f7bd43a71c8d2a58e369e9b2bf692d1334ea9f9cae55add7d0dd0f84", "sha256:fdb6d215c776278489906c2f8916e6e7d4f5a9b602ccbcfdf7f016fc8da0596e" ], - "markers": "python_version >= '3.7'", + "markers": "python_version >= '3.6'", "version": "==2.0.7" }, "vine": { @@ -2161,11 +2177,11 @@ }, "faker": { "hashes": [ - "sha256:2b57f0256da6b45b7851dca87836ef5e2ae2fbb64d63d8697f1e47830d7b505d", - "sha256:fa6d969728ef3da6229da91267a1bd4e6b902044c4822012d4fc46c71bb92b26" + "sha256:0520a6b97e07c658b2798d7140971c1d5bc4bcd5013e7937fe075fd054aa320c", + "sha256:f07b64d27f67b62c7f0536a72f47813015b3b51cd4664918454011094321e464" ], "markers": "python_version >= '3.8'", - "version": "==22.6.0" + "version": "==23.2.1" }, "filelock": { "hashes": [ @@ -2195,11 +2211,11 @@ }, "identify": { "hashes": [ - "sha256:161558f9fe4559e1557e1bff323e8631f6a0e4837f7497767c1782832f16b62d", - "sha256:d40ce5fcd762817627670da8a7d8d8e65f24342d14539c59488dc603bf662e34" + "sha256:10a7ca245cfcd756a554a7288159f72ff105ad233c7c4b9c6f0f4d108f5f6791", + "sha256:c4de0081837b211594f8e877a6b4fad7ca32bbfc1a9307fdd61c28bfe923f13e" ], "markers": "python_version >= '3.8'", - "version": "==2.5.33" + "version": "==2.5.35" }, "ipdb": { "hashes": [ @@ -2509,11 +2525,11 @@ }, "setuptools": { "hashes": [ - "sha256:385eb4edd9c9d5c17540511303e39a147ce2fc04bc55289c322b9e5904fe2c05", - "sha256:be1af57fc409f93647f2e8e4573a142ed38724b8cdd389706a867bb4efcf1e78" + "sha256:850894c4195f09c4ed30dba56213bf7c3f21d86ed6bdaafb5df5972593bfc401", + "sha256:c054629b81b946d63a9c6e732bc8b2513a7c3ea645f11d0139a2191d735c60c6" ], "markers": "python_version >= '3.8'", - "version": "==69.0.3" + "version": "==69.1.0" }, "six": { "hashes": [ @@ -2562,6 +2578,42 @@ "markers": "python_version >= '3.7'", "version": "==20.25.0" }, + "watchdog": { + "hashes": [ + "sha256:11e12fafb13372e18ca1bbf12d50f593e7280646687463dd47730fd4f4d5d257", + "sha256:2895bf0518361a9728773083908801a376743bcc37dfa252b801af8fd281b1ca", + "sha256:39cb34b1f1afbf23e9562501673e7146777efe95da24fab5707b88f7fb11649b", + "sha256:45cc09cc4c3b43fb10b59ef4d07318d9a3ecdbff03abd2e36e77b6dd9f9a5c85", + "sha256:4986db5e8880b0e6b7cd52ba36255d4793bf5cdc95bd6264806c233173b1ec0b", + "sha256:5369136a6474678e02426bd984466343924d1df8e2fd94a9b443cb7e3aa20d19", + "sha256:557ba04c816d23ce98a06e70af6abaa0485f6d94994ec78a42b05d1c03dcbd50", + "sha256:6a4db54edea37d1058b08947c789a2354ee02972ed5d1e0dca9b0b820f4c7f92", + "sha256:6a80d5cae8c265842c7419c560b9961561556c4361b297b4c431903f8c33b269", + "sha256:6a9c71a0b02985b4b0b6d14b875a6c86ddea2fdbebd0c9a720a806a8bbffc69f", + "sha256:6c47bdd680009b11c9ac382163e05ca43baf4127954c5f6d0250e7d772d2b80c", + "sha256:6e949a8a94186bced05b6508faa61b7adacc911115664ccb1923b9ad1f1ccf7b", + "sha256:73c7a935e62033bd5e8f0da33a4dcb763da2361921a69a5a95aaf6c93aa03a87", + "sha256:76ad8484379695f3fe46228962017a7e1337e9acadafed67eb20aabb175df98b", + "sha256:8350d4055505412a426b6ad8c521bc7d367d1637a762c70fdd93a3a0d595990b", + "sha256:87e9df830022488e235dd601478c15ad73a0389628588ba0b028cb74eb72fed8", + "sha256:8f9a542c979df62098ae9c58b19e03ad3df1c9d8c6895d96c0d51da17b243b1c", + "sha256:8fec441f5adcf81dd240a5fe78e3d83767999771630b5ddfc5867827a34fa3d3", + "sha256:9a03e16e55465177d416699331b0f3564138f1807ecc5f2de9d55d8f188d08c7", + "sha256:ba30a896166f0fee83183cec913298151b73164160d965af2e93a20bbd2ab605", + "sha256:c17d98799f32e3f55f181f19dd2021d762eb38fdd381b4a748b9f5a36738e935", + "sha256:c522392acc5e962bcac3b22b9592493ffd06d1fc5d755954e6be9f4990de932b", + "sha256:d0f9bd1fd919134d459d8abf954f63886745f4660ef66480b9d753a7c9d40927", + "sha256:d18d7f18a47de6863cd480734613502904611730f8def45fc52a5d97503e5101", + "sha256:d31481ccf4694a8416b681544c23bd271f5a123162ab603c7d7d2dd7dd901a07", + "sha256:e3e7065cbdabe6183ab82199d7a4f6b3ba0a438c5a512a68559846ccb76a78ec", + "sha256:eed82cdf79cd7f0232e2fdc1ad05b06a5e102a43e331f7d041e5f0e0a34a51c4", + "sha256:f970663fa4f7e80401a7b0cbeec00fa801bf0287d93d48368fc3e6fa32716245", + "sha256:f9b2fdca47dc855516b2d66eef3c39f2672cbf7e7a42e7e67ad2cbfcd6ba107d" + ], + "index": "pypi", + "markers": "python_version >= '3.8'", + "version": "==4.0.0" + }, "wcwidth": { "hashes": [ "sha256:3da69048e4540d84af32131829ff948f1e022c1c6bdb8d6102117aac784f6859", diff --git a/ayushma/admin.py b/ayushma/admin.py index ceb68ae7..b86cd670 100644 --- a/ayushma/admin.py +++ b/ayushma/admin.py @@ -1,7 +1,6 @@ from django.contrib import admin from django.contrib.auth.admin import UserAdmin as BaseUserAdmin from djangoql.admin import DjangoQLSearchMixin -from simple_history.admin import SimpleHistoryAdmin from ayushma.models.services import Service, TempToken from ayushma.models.testsuite import Feedback, TestQuestion, TestRun, TestSuite @@ -32,7 +31,15 @@ class UserAdmin(DjangoQLSearchMixin, BaseUserAdmin): fieldsets = ( ( None, - {"fields": ("email", "username", "password", "external_id", "allow_key")}, + { + "fields": ( + "email", + "username", + "password", + "external_id", + "allow_key", + ) + }, ), ( "User info", diff --git a/ayushma/apps.py b/ayushma/apps.py index a0be6977..ae9c4b39 100644 --- a/ayushma/apps.py +++ b/ayushma/apps.py @@ -6,5 +6,5 @@ class AyushmaConfig(AppConfig): name = "ayushma" def ready(self): - #from .signals import # noqa: F401 + # from .signals import # noqa: F401 pass diff --git a/ayushma/management/commands/upsert.py b/ayushma/management/commands/upsert.py index a239f19e..69694318 100644 --- a/ayushma/management/commands/upsert.py +++ b/ayushma/management/commands/upsert.py @@ -31,7 +31,8 @@ class Command(BaseCommand): def handle(self, *args, **options): upsert_dir = "upsert" pinecone.init( - api_key=settings.PINECONE_API_KEY, environment=settings.PINECONE_ENVIRONMENT + api_key=settings.PINECONE_API_KEY, + environment=settings.PINECONE_ENVIRONMENT, ) print("Initialized Pinecone and OpenAI") @@ -49,7 +50,7 @@ def handle(self, *args, **options): batch_size = 100 # process everything in batches of 100 (creates 100 vectors per upset) - print(f"Fetching Pinecone index...") + print("Fetching Pinecone index...") if settings.PINECONE_INDEX not in pinecone.list_indexes(): pinecone.create_index( settings.PINECONE_INDEX, diff --git a/ayushma/migrations/0052_document_failed.py b/ayushma/migrations/0052_document_failed.py new file mode 100644 index 00000000..fc391be4 --- /dev/null +++ b/ayushma/migrations/0052_document_failed.py @@ -0,0 +1,17 @@ +# Generated by Django 4.2.6 on 2024-04-17 13:56 + +from django.db import migrations, models + + +class Migration(migrations.Migration): + dependencies = [ + ("ayushma", "0051_project_tts_engine"), + ] + + operations = [ + migrations.AddField( + model_name="document", + name="failed", + field=models.BooleanField(default=False), + ), + ] diff --git a/ayushma/models/document.py b/ayushma/models/document.py index 55c2d1be..95602cff 100644 --- a/ayushma/models/document.py +++ b/ayushma/models/document.py @@ -19,6 +19,7 @@ class Document(BaseModel): "TestQuestion", on_delete=models.PROTECT, null=True, blank=True ) uploading = models.BooleanField(default=True) + failed = models.BooleanField(default=False) def __str__(self) -> str: return f"{self.title} in {self.project.title}" diff --git a/ayushma/models/enums.py b/ayushma/models/enums.py index a7a7c9cb..0a856e94 100644 --- a/ayushma/models/enums.py +++ b/ayushma/models/enums.py @@ -18,6 +18,13 @@ class STTEngine(IntegerChoices): GOOGLE = 2 SELF_HOSTED = 3 + @classmethod + def get_id_from_name(cls, name): + for member in cls: + if member.name.lower() == name.lower(): + return member.value + return None + class TTSEngine(IntegerChoices): OPENAI = (1, "openai") diff --git a/ayushma/models/services.py b/ayushma/models/services.py index 0f9db546..6b961eb9 100644 --- a/ayushma/models/services.py +++ b/ayushma/models/services.py @@ -1,5 +1,4 @@ import secrets -import time from django.db import models from django.utils import timezone diff --git a/ayushma/models/token.py b/ayushma/models/token.py index 5aab6450..b9a3452a 100644 --- a/ayushma/models/token.py +++ b/ayushma/models/token.py @@ -1,6 +1,6 @@ +from django.conf import settings from django.db import models from django.utils.translation import gettext_lazy as _ -from django.conf import settings from ayushma.token import RandomStringTokenGenerator from utils.models.base import BaseModel @@ -11,9 +11,7 @@ class ResetPasswordToken(BaseModel): settings.AUTH_USER_MODEL, related_name="password_reset_tokens", on_delete=models.CASCADE, - verbose_name=_( - "The User which is associated to this password reset token" - ), + verbose_name=_("The User which is associated to this password reset token"), ) created_at = models.DateTimeField( auto_now_add=True, verbose_name=_("When was this token generated") diff --git a/ayushma/permissions.py b/ayushma/permissions.py index a6005929..09166692 100644 --- a/ayushma/permissions.py +++ b/ayushma/permissions.py @@ -1,5 +1,3 @@ -from ipaddress import ip_address - from django.utils import timezone from rest_framework import permissions diff --git a/ayushma/serializers/document.py b/ayushma/serializers/document.py index 1d727445..bb57027d 100644 --- a/ayushma/serializers/document.py +++ b/ayushma/serializers/document.py @@ -1,12 +1,6 @@ -import os -import uuid - -from django.conf import settings -from django.core.files.storage import FileSystemStorage from rest_framework import serializers -from rest_framework.response import Response -from ayushma.models import Document, DocumentType +from ayushma.models import Document class DocumentSerializer(serializers.ModelSerializer): @@ -23,7 +17,12 @@ class Meta: "text_content", "uploading", ) - read_only_fields = ("external_id", "created_at", "modified_at", "uploading") + read_only_fields = ( + "external_id", + "created_at", + "modified_at", + "uploading", + ) write_only_fields = ("file",) def validate(self, data): diff --git a/ayushma/serializers/testsuite.py b/ayushma/serializers/testsuite.py index a9fc33f2..5e7e07d2 100644 --- a/ayushma/serializers/testsuite.py +++ b/ayushma/serializers/testsuite.py @@ -9,7 +9,7 @@ TestSuite, ) from ayushma.serializers.document import DocumentSerializer -from ayushma.serializers.project import ProjectSerializer, ProjectUpdateSerializer +from ayushma.serializers.project import ProjectUpdateSerializer from ayushma.serializers.users import UserSerializer @@ -67,7 +67,12 @@ class Meta: "modified_at", ) - read_only_fields = ("user_object", "external_id", "created_at", "modified_at") + read_only_fields = ( + "user_object", + "external_id", + "created_at", + "modified_at", + ) class TestResultSerializer(serializers.ModelSerializer): diff --git a/ayushma/serializers/users.py b/ayushma/serializers/users.py index c4cee45a..edb5f375 100644 --- a/ayushma/serializers/users.py +++ b/ayushma/serializers/users.py @@ -16,6 +16,7 @@ class Meta: "allow_key", "is_staff", "is_reviewer", + "date_joined", ) @@ -56,6 +57,7 @@ class Meta: "is_staff", "is_reviewer", "password", + "date_joined", ) read_only_fields = ( "external_id", @@ -64,6 +66,7 @@ class Meta: "allow_key", "is_staff", "is_reviewer", + "date_joined", ) def update(self, instance, validated_data): diff --git a/ayushma/tasks/__init__.py b/ayushma/tasks/__init__.py index e69de29b..275c5ba5 100644 --- a/ayushma/tasks/__init__.py +++ b/ayushma/tasks/__init__.py @@ -0,0 +1,18 @@ +from celery import current_app +from celery.schedules import crontab + +from ayushma.tasks.stale_cleanup import clean_stale_test_runs, clean_stale_upsert_doc + + +@current_app.on_after_finalize.connect +def setup_periodic_tasks(sender, **kwargs): + sender.add_periodic_task( + crontab(minute="*/30"), # Every 30 minutes + clean_stale_test_runs.s(), + name="clean_stale_test_runs", + ) + sender.add_periodic_task( + crontab(minute="*/30"), # Every 30 minutes + clean_stale_upsert_doc.s(), + name="clean_stale_upsert_doc", + ) diff --git a/ayushma/tasks/stale_cleanup.py b/ayushma/tasks/stale_cleanup.py new file mode 100644 index 00000000..372d515f --- /dev/null +++ b/ayushma/tasks/stale_cleanup.py @@ -0,0 +1,52 @@ +from datetime import timedelta + +from celery import shared_task +from django.utils.timezone import now + +from ayushma.models.document import Document +from ayushma.models.enums import StatusChoices +from ayushma.models.testsuite import TestRun + + +@shared_task(bind=True) +def clean_stale_test_runs(self): + try: + # Get testRuns that are created over 6 hours ago and are still in RUNNING state + test_runs = TestRun.objects.filter( + created_at__lt=now() - timedelta(hours=6), + status=StatusChoices.RUNNING, + ) + + # Cancel the testRuns + for test_run in test_runs: + print( + f"Cleaning stale test run: {test_run.id}; Created at: {test_run.created_at}" + ) + test_run.status = StatusChoices.FAILED + test_run.save() + except Exception as e: + print(f"Error occurred while cleaning stale test runs: {e}") + raise e + + +@shared_task(bind=True) +def clean_stale_upsert_doc(self): + try: + # Get stale Document objects that are still in UPLOADING state after 6 hours + documents = Document.objects.filter( + created_at__lt=now() - timedelta(hours=6), + uploading=True, + ) + + # Set the documents to failed state + for document in documents: + print( + f"Cleaning stale document: {document.id}; Created at: {document.created_at}" + ) + document.failed = True + document.uploading = False + document.save() + + except Exception as e: + print(f"Error occurred while cleaning stale test runs: {e}") + raise e diff --git a/ayushma/token.py b/ayushma/token.py index ade3bd71..b95fbb6a 100644 --- a/ayushma/token.py +++ b/ayushma/token.py @@ -7,6 +7,4 @@ def __init__(self, length=6): self.length = length def generate(self): - return "".join( - [random.choice(string.digits) for _ in range(self.length)] - ) + return "".join([random.choice(string.digits) for _ in range(self.length)]) diff --git a/ayushma/utils/converse.py b/ayushma/utils/converse.py index 19ea4aca..aa325588 100644 --- a/ayushma/utils/converse.py +++ b/ayushma/utils/converse.py @@ -47,7 +47,7 @@ def converse_api( if not open_ai_key: open_ai_key = ( request.headers.get("OpenAI-Key") - or (chat.project.open_ai_key) + or (chat.project and chat.project.open_ai_key) or (user.allow_key and settings.OPENAI_API_KEY) ) noonce = request.data.get("noonce") @@ -73,7 +73,7 @@ def converse_api( converse_type = "audio" if audio else "text" # convert stream to boolean - if type(stream) != bool: + if not isinstance(stream, bool): if stream == "false": stream = False else: @@ -82,7 +82,7 @@ def converse_api( if is_thread: stream = False # Threads do not support streaming - if type(generate_audio) != bool: + if not isinstance(generate_audio, bool): if generate_audio == "false": generate_audio = False else: @@ -118,9 +118,9 @@ def converse_api( # store time to complete request stats["start_time"] = time.time() if converse_type == "audio" and not audio: - return Exception("Please provide audio to generate transcript") + return Exception("[Converse] Please provide audio to generate transcript") if converse_type == "text" and not text: - return Exception("Please provide text to generate transcript") + return Exception("[Converse] Please provide text to generate transcript") if converse_type == "audio": stats["transcript_start_time"] = time.time() @@ -195,7 +195,8 @@ def converse_api( response_message = list(response_message)[0] return Response( - ChatMessageSerializer(response_message).data, status=status.HTTP_200_OK + ChatMessageSerializer(response_message).data, + status=status.HTTP_200_OK, ) return response diff --git a/ayushma/utils/language_helpers.py b/ayushma/utils/language_helpers.py index 460e2093..c42a8209 100644 --- a/ayushma/utils/language_helpers.py +++ b/ayushma/utils/language_helpers.py @@ -16,8 +16,8 @@ def translate_text(target, text): result = translate_client.translate(text, target_language=target) return result["translatedText"] except Exception as e: - print(e) - raise APIException("Translation failed") + print(f"Translation failed: {e}") + raise APIException("[Translation] Failed to translate the text") language_code_voice_map = { @@ -55,7 +55,8 @@ def text_to_speech(text, language_code, service): synthesis_input = texttospeech.SynthesisInput(text=text) voice = texttospeech.VoiceSelectionParams( - language_code=language_code, name=language_code_voice_map[language_code] + language_code=language_code, + name=language_code_voice_map[language_code], ) audio_config = texttospeech.AudioConfig( audio_encoding=texttospeech.AudioEncoding.MP3 @@ -77,7 +78,7 @@ def text_to_speech(text, language_code, service): ) return response.read() else: - raise APIException("Service not supported") + raise APIException("[Text to Speech] Service not supported.") except Exception as e: - print(e) - return None + print(f"Failed to convert text to speech: {e}") + raise APIException("[Text to Speech] Failed to convert text to speech.") diff --git a/ayushma/utils/openaiapi.py b/ayushma/utils/openaiapi.py index 2326d5ff..c82da95d 100644 --- a/ayushma/utils/openaiapi.py +++ b/ayushma/utils/openaiapi.py @@ -94,7 +94,7 @@ def get_sanitized_reference(pinecone_references: List[QueryResponse]) -> str: else: sanitized_reference[document_id] = text except Exception as e: - print(e) + print(f"Error extracting reference: {e}") pass return json.dumps(sanitized_reference) @@ -143,17 +143,17 @@ def get_reference(text, openai_key, namespace, top_k): try: embeddings.append(get_embedding(text=[text], openai_api_key=openai_key)) except Exception as e: - return Exception( - e.__str__(), - ) + print(f"Error generating embeddings: {e}") + return Exception("[Reference] Error generating embeddings") else: parts = split_text(text) for part in parts: try: embeddings.append(get_embedding(text=[part], openai_api_key=openai_key)) except Exception as e: + print(f"Error generating embeddings: {e}") raise Exception( - e.__str__(), + "[Reference] Error generating embeddings for split text" ) # find similar embeddings from pinecone index for each embedding pinecone_references: List[QueryResponse] = [] @@ -187,7 +187,7 @@ def add_reference_documents(chat_message): except Document.DoesNotExist: pass except Exception as e: - print("Error adding reference documents: ", e) + print(f"Error adding reference documents: {e}") chat_message.original_message = chat_text[ :ref_start_idx @@ -297,10 +297,13 @@ def converse( elif fetch_references and chat.project and chat.project.external_id: try: reference = get_reference( - english_text, openai_key, str(chat.project.external_id), match_number + english_text, + openai_key, + str(chat.project.external_id), + match_number, ) except Exception as e: - print(e) + print(f"Error fetching references: {e}") reference = "" else: reference = "" @@ -311,7 +314,7 @@ def converse( prompt = chat.prompt or (chat.project and chat.project.prompt) - if documents or chat.project.model == ModelType.GPT_4_VISUAL: + if documents or (chat.project and chat.project.model == ModelType.GPT_4_VISUAL): prompt = "Image Capabilities: Enabled\n" + prompt # excluding the latest query since it is not a history @@ -327,7 +330,7 @@ def converse( elif message.messageType == ChatMessageType.AYUSHMA: chat_history.append(AIMessage(content=f"Ayushma: {message.message}")) - tts_engine = chat.project.tts_engine + tts_engine = chat.project and chat.project.tts_engine if not stream: lang_chain_helper = LangChainHelper( @@ -342,7 +345,7 @@ def converse( response = lang_chain_helper.get_response( english_text, reference, chat_history, documents ) - chat_response = response.replace("Ayushma: ", "") + chat_response = response.replace(f"{AI_NAME}:", "").lstrip() stats["response_end_time"] = time.time() translated_chat_response, url, chat_message = handle_post_response( chat_response, @@ -388,8 +391,6 @@ def converse( documents, ) chat_response = "" - skip_token = len(f"{AI_NAME}: ") - while True: if token_queue.empty(): continue @@ -424,10 +425,9 @@ def converse( ayushma_voice=url, ) break - if skip_token > 0: - skip_token -= 1 - continue + chat_response += next_token[0] + chat_response = chat_response.replace(f"{AI_NAME}:", "").lstrip() yield create_json_response( local_translated_text, chat.external_id, @@ -438,8 +438,10 @@ def converse( None, ) except Exception as e: - print(e) - error_text = str(e) + print(f"Error in streaming response: {e}") + error_text = ( + "[Streaming] Something went wrong in getting response, stream stopped" + ) translated_error_text = error_text if user_language != "en-IN": translated_error_text = translate_text(user_language, error_text) @@ -464,7 +466,13 @@ def converse( }, ) yield create_json_response( - local_translated_text, chat.external_id, "", str(e), True, True, None + local_translated_text, + chat.external_id, + "", + str(e), + True, + True, + None, ) @@ -499,7 +507,8 @@ def converse_thread( if status == "completed": break else: - raise Exception("Thread timed out") + print("[Thread] Run did not complete, timed out") + raise Exception("[Thread] Run did not complete, timed out") response = ( client.beta.threads.messages.list(thread_id=thread.thread_id) diff --git a/ayushma/utils/speech_to_text.py b/ayushma/utils/speech_to_text.py index 551ba73e..a004ebd9 100644 --- a/ayushma/utils/speech_to_text.py +++ b/ayushma/utils/speech_to_text.py @@ -14,15 +14,21 @@ def __init__(self, api_key, language_code): self.language_code = language_code def recognize(self, audio): - client = OpenAI(api_key=self.api_key) - transcription = client.audio.transcriptions.create( - model="whisper-1", - # https://github.com/openai/openai-python/tree/main#file-uploads - file=(audio.name, audio.read()), - language=self.language_code.replace("-IN", ""), - # api_version="2020-11-07", - ) - return transcription.text + try: + client = OpenAI(api_key=self.api_key) + transcription = client.audio.transcriptions.create( + model="whisper-1", + # https://github.com/openai/openai-python/tree/main#file-uploads + file=(audio.name, audio.read()), + language=self.language_code.replace("-IN", ""), + # api_version="2020-11-07", + ) + return transcription.text + except Exception as e: + print(f"Failed to recognize speech with whisper engine: {e}") + raise ValueError( + "[Speech to Text] Failed to recognize speech with Whisper engine" + ) class GoogleEngine: @@ -31,19 +37,25 @@ def __init__(self, api_key, language_code): self.language_code = language_code def recognize(self, audio): - client = speech.SpeechClient() - audio_content = audio.file.read() - audio_data = speech.RecognitionAudio(content=audio_content) - - config = speech.RecognitionConfig( - encoding=speech.RecognitionConfig.AudioEncoding.ENCODING_UNSPECIFIED, - language_code=self.language_code, - ) - - response = client.recognize(config=config, audio=audio_data) - if not response.results: - return "" - return response.results[0].alternatives[0].transcript + try: + client = speech.SpeechClient() + audio_content = audio.file.read() + audio_data = speech.RecognitionAudio(content=audio_content) + + config = speech.RecognitionConfig( + encoding=speech.RecognitionConfig.AudioEncoding.ENCODING_UNSPECIFIED, + language_code=self.language_code, + ) + + response = client.recognize(config=config, audio=audio_data) + if not response.results: + return "" + return response.results[0].alternatives[0].transcript + except Exception as e: + print(f"Failed to recognize speech with google engine: {e}") + raise ValueError( + "[Speech to Text] Failed to recognize speech with Google engine" + ) class SelfHostedEngine: @@ -51,21 +63,26 @@ def __init__(self, api_key, language_code): self.language_code = language_code def recognize(self, audio): - response = requests.post( - settings.SELF_HOSTED_ENDPOINT, - files={"audio": audio}, - data={ - # change this model to get faster results see: https://github.com/coronasafe/care-whisper - "model": "small", - "language": self.language_code.replace("-IN", ""), - }, - ) - - if not response.ok: - print("Failed to recognize speech with self hosted engine") - return "" - response = response.json() - return response["data"]["transcription"].strip() + try: + response = requests.post( + settings.SELF_HOSTED_ENDPOINT, + files={"audio": audio}, + data={ + # change this model to get faster results see: https://github.com/coronasafe/care-whisper + "model": "small", + "language": self.language_code.replace("-IN", ""), + }, + ) + + if not response.ok: + print("Failed to recognize speech with self hosted engine") + return "" + response = response.json() + return response["data"]["transcription"].strip() + except Exception: + raise ValueError( + "[Speech to Text] Failed to recognize speech with Self Hosted engine" + ) engines = { @@ -82,14 +99,17 @@ def speech_to_text(engine_id, audio, language_code): engine_class = engines.get(engine_name) if not engine_class: - raise ValueError(f"Invalid STT engine ID: {engine_id}") + print(f"Invalid Speech to Text engine: {engine_name}") + raise ValueError("The selected Speech to Text engine is not valid") try: engine = engine_class(api_key, language_code) recognized_text = engine.recognize(audio) if not recognized_text: - raise ValueError("Failed to detect any speech in provided audio") + raise ValueError("No text recognized in the audio") return recognized_text except Exception as e: - print(f"Failed to recognize speech with {engine_name} engine: {e}") - raise e + print(f"Failed to transcribe speech with {engine_name} engine: {e}") + raise ValueError( + f"[Speech to Text] Failed to transcribe speech with {engine_name} engine: {e}" + ) diff --git a/ayushma/utils/upsert.py b/ayushma/utils/upsert.py index 5c85353e..13727e17 100644 --- a/ayushma/utils/upsert.py +++ b/ayushma/utils/upsert.py @@ -58,7 +58,8 @@ def upsert( None """ pinecone.init( - api_key=settings.PINECONE_API_KEY, environment=settings.PINECONE_ENVIRONMENT + api_key=settings.PINECONE_API_KEY, + environment=settings.PINECONE_ENVIRONMENT, ) print("Initialized Pinecone and OpenAI") @@ -80,7 +81,9 @@ def upsert( raise Exception("Either filepath, url or text must be provided") if len(document_lines) == 0: - raise Exception("No text found in document") + raise Exception( + "[Upsert] No text found in the document. Please check the document." + ) print(document_lines) batch_size = ( diff --git a/ayushma/views/auth.py b/ayushma/views/auth.py index bb7a78f6..ed64f40f 100644 --- a/ayushma/views/auth.py +++ b/ayushma/views/auth.py @@ -1,19 +1,14 @@ -from drf_spectacular.utils import ( - extend_schema, - OpenApiResponse, -) +from drf_spectacular.utils import OpenApiResponse, extend_schema from rest_framework import status -from rest_framework.viewsets import GenericViewSet -from rest_framework.decorators import action -from rest_framework.response import Response from rest_framework.authtoken.models import Token +from rest_framework.decorators import action from rest_framework.exceptions import ParseError from rest_framework.permissions import AllowAny +from rest_framework.response import Response +from rest_framework.viewsets import GenericViewSet from ayushma.serializers.auth import AuthSerializer -from ayushma.serializers.users import ( - UserCreateSerializer, -) +from ayushma.serializers.users import UserCreateSerializer class AuthViewSet(GenericViewSet): diff --git a/ayushma/views/chat.py b/ayushma/views/chat.py index c6f72163..0a76686f 100644 --- a/ayushma/views/chat.py +++ b/ayushma/views/chat.py @@ -3,7 +3,7 @@ from django.conf import settings from drf_spectacular.utils import extend_schema from rest_framework import filters, status -from rest_framework.decorators import action, api_view, permission_classes +from rest_framework.decorators import action from rest_framework.exceptions import ValidationError from rest_framework.mixins import ( CreateModelMixin, @@ -16,6 +16,8 @@ from rest_framework.response import Response from ayushma.models import Chat, ChatFeedback, Project +from ayushma.models.chat import ChatMessage +from ayushma.models.enums import ChatMessageType from ayushma.permissions import IsTempTokenOrAuthenticated from ayushma.serializers import ( ChatDetailSerializer, @@ -122,7 +124,8 @@ def speech_to_text(self, *args, **kwarg): stt_engine = Project.objects.get(external_id=project_id).stt_engine except Project.DoesNotExist: return Response( - {"error": "Project not found"}, status=status.HTTP_400_BAD_REQUEST + {"error": "Project not found"}, + status=status.HTTP_400_BAD_REQUEST, ) try: stats["transcript_start_time"] = time.time() @@ -130,16 +133,31 @@ def speech_to_text(self, *args, **kwarg): stats["transcript_end_time"] = time.time() translated_text = transcript except Exception as e: - print(f"Failed to transcribe speech with {stt_engine} engine: {e}") + print(f"Failed to transcribe speech with {stt_engine} engine:\n{e}") + + error_msg = ( + f"[Transcribing] Something went wrong in getting transcription.\n{e}" + ) + chat = Chat.objects.get(external_id=kwarg["external_id"]) + chat.title = "Transcription Error" + chat.save() + ChatMessage.objects.create( + message=error_msg, + original_message=error_msg, + chat=chat, + messageType=ChatMessageType.SYSTEM, + language=language, + meta={}, + ) + return Response( - { - "error": "Something went wrong in getting transcription, please try again later" - }, + {"error": error_msg}, status=status.HTTP_500_INTERNAL_SERVER_ERROR, ) return Response( - {"transcript": translated_text, "stats": stats}, status=status.HTTP_200_OK + {"transcript": translated_text, "stats": stats}, + status=status.HTTP_200_OK, ) @extend_schema( diff --git a/ayushma/views/orphan.py b/ayushma/views/orphan.py index ff3d0751..0d94abb6 100644 --- a/ayushma/views/orphan.py +++ b/ayushma/views/orphan.py @@ -1,27 +1,29 @@ -import time -from types import SimpleNamespace - import openai from django.conf import settings -from django.http import StreamingHttpResponse -from drf_spectacular.utils import extend_schema, extend_schema_view, inline_serializer +from drf_spectacular.utils import extend_schema from rest_framework import permissions, status from rest_framework.decorators import action from rest_framework.exceptions import ValidationError from rest_framework.mixins import CreateModelMixin, ListModelMixin, RetrieveModelMixin from rest_framework.parsers import MultiPartParser from rest_framework.response import Response -from rest_framework.serializers import CharField, IntegerField -from ayushma.models import APIKey, Chat, ChatMessage, Project +from ayushma.models import APIKey, Chat +from ayushma.models.enums import STTEngine from ayushma.serializers import ChatDetailSerializer, ConverseSerializer from ayushma.utils.converse import converse_api -from ayushma.utils.language_helpers import translate_text -from ayushma.utils.openaiapi import converse +from ayushma.utils.speech_to_text import speech_to_text from utils.views.base import BaseModelViewSet from utils.views.mixins import PartialUpdateModelMixin -from .chat import ChatViewSet +PREDEFINED_CONFIGS = { + "ai_form_fill": { + "model": "gpt-4-turbo-preview", + "response_format": "json_object", + "max_tokens": 4096, + "temperature": 0, + }, +} class Struct: @@ -33,11 +35,7 @@ class APIKeyAuth(permissions.BasePermission): def has_permission(self, request, view): if request.headers.get("X-API-KEY"): api_key = request.headers.get("X-API-KEY") - try: - key = APIKey.objects.get(key=api_key) - return True - except APIKey.DoesNotExist: - return False + return APIKey.objects.filter(key=api_key).exists() class OrphanChatViewSet( @@ -82,6 +80,7 @@ def create(self, request, *args, **kwargs): response = converse_api( request=self.request, chat=chat, + is_thread=False, ) return Response( { @@ -110,7 +109,57 @@ def converse(self, *args, **kwarg): response = converse_api( request=self.request, chat=chat, + is_thread=False, ) return response except Exception as e: return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) + + @action(detail=False, methods=["post"]) + def transcribe(self, request, *args, **kwargs): + language = request.data.get("language") or "en" + audio = request.data.get("audio") + engine = request.data.get("engine") + if not audio or not engine: + raise ValidationError("audio and engine are required") + try: + engine_id = STTEngine.get_id_from_name(engine) + transcript = speech_to_text(engine_id, audio, language + "-IN") + return Response({"transcript": transcript}) + except Exception as e: + return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) + + @action(detail=False, methods=["post"]) + def completion(self, request, *args, **kwargs): + task = request.data.get("task") + + if not task: + raise ValidationError("task is required") + + config = PREDEFINED_CONFIGS.get(task) + + if not config: + raise ValidationError("Invalid task") + + model = config.get("model") + response_format = config.get("response_format") + max_tokens = config.get("max_tokens") + temperature = config.get("temperature") + + messages = request.data.get("messages") + if not messages or len(messages) == 0: + raise ValidationError("audio and engine are required") + try: + client = openai.OpenAI(api_key=settings.OPENAI_API_KEY) + completion = client.chat.completions.create( + model=model, + temperature=temperature, + response_format={"type": response_format}, + messages=messages, + max_tokens=max_tokens, + ) + + ai_response = completion.choices[0].message.content + return Response({"response": ai_response}) + except Exception as e: + return Response({"error": str(e)}, status=status.HTTP_400_BAD_REQUEST) diff --git a/ayushma/views/project.py b/ayushma/views/project.py index 6de7ff85..091be342 100644 --- a/ayushma/views/project.py +++ b/ayushma/views/project.py @@ -26,8 +26,12 @@ class ProjectViewSet( CreateModelMixin, DestroyModelMixin, ): - queryset = Project.objects.all() - filter_backends = (filters.SearchFilter, DjangoFilterBackend) + queryset = Project.objects.all().order_by("-is_default") + filter_backends = ( + filters.SearchFilter, + DjangoFilterBackend, + filters.OrderingFilter, + ) search_fields = ("title",) filterset_fields = ("archived",) serializer_class = ProjectSerializer @@ -56,7 +60,7 @@ def get_queryset(self): if self.action == "list": if not self.request.user.is_staff: queryset = self.queryset.filter(is_default=True) - return queryset + return queryset.order_by("-is_default") def perform_create(self, serializer): serializer.save(creator=self.request.user) diff --git a/ayushma/views/service.py b/ayushma/views/service.py index 04a7b8a9..d9a3396a 100644 --- a/ayushma/views/service.py +++ b/ayushma/views/service.py @@ -1,28 +1,10 @@ -import time -from types import SimpleNamespace - -import openai -from django.conf import settings -from django.http import StreamingHttpResponse -from drf_spectacular.utils import extend_schema, extend_schema_view, inline_serializer -from rest_framework import permissions, status -from rest_framework.decorators import action -from rest_framework.exceptions import ValidationError +from rest_framework import permissions from rest_framework.mixins import CreateModelMixin -from rest_framework.parsers import MultiPartParser -from rest_framework.response import Response -from rest_framework.serializers import CharField, IntegerField -from ayushma.models import APIKey, Chat, ChatMessage, Project -from ayushma.serializers import ChatDetailSerializer, ConverseSerializer +from ayushma.models import APIKey from ayushma.serializers.services import TempTokenSerializer -from ayushma.utils.converse import converse_api -from ayushma.utils.language_helpers import translate_text -from ayushma.utils.openaiapi import converse from utils.views.base import BaseModelViewSet -from .chat import ChatViewSet - class Struct: def __init__(self, **entries): @@ -33,11 +15,7 @@ class APIKeyAuth(permissions.BasePermission): def has_permission(self, request, view): if request.headers.get("X-API-KEY"): api_key = request.headers.get("X-API-KEY") - try: - key = APIKey.objects.get(key=api_key) - return True - except APIKey.DoesNotExist: - return False + return APIKey.objects.filter(key=api_key).exists() class TempTokenViewSet(BaseModelViewSet, CreateModelMixin): diff --git a/ayushma/views/token.py b/ayushma/views/token.py index 7857f5fc..8af0e901 100644 --- a/ayushma/views/token.py +++ b/ayushma/views/token.py @@ -148,7 +148,7 @@ def validation(password): # find the token try: - reset_password_token = ResetPasswordToken.objects.get(key=token) + ResetPasswordToken.objects.get(key=token) except ResetPasswordToken.DoesNotExist: return Response(status=status.HTTP_400_BAD_REQUEST) diff --git a/ayushma/views/users.py b/ayushma/views/users.py index f13bfe0e..b68949ea 100644 --- a/ayushma/views/users.py +++ b/ayushma/views/users.py @@ -1,8 +1,7 @@ from django_filters.rest_framework import DjangoFilterBackend from drf_spectacular.utils import extend_schema -from rest_framework import permissions +from rest_framework import filters, permissions from rest_framework.decorators import action -from rest_framework.filters import SearchFilter from ayushma.models import User from ayushma.serializers.users import ( @@ -15,7 +14,12 @@ class UserViewSet(FullBaseModelViewSet): - queryset = User.objects.all() + queryset = User.objects.all().order_by("-date_joined") + filter_backends = ( + filters.SearchFilter, + DjangoFilterBackend, + filters.OrderingFilter, + ) serializer_class = UserDetailSerializer permission_classes = (permissions.IsAdminUser,) serializer_action_classes = { @@ -29,7 +33,6 @@ class UserViewSet(FullBaseModelViewSet): "partial_update_me": (permissions.IsAuthenticated(),), } lookup_field = "username" - filter_backends = [SearchFilter, DjangoFilterBackend] search_fields = ["full_name"] filterset_fields = ["is_staff", "is_reviewer", "allow_key"] diff --git a/compose/local/django/celery/beat/start b/compose/local/django/celery/beat/start index 0d318fb8..36daca83 100644 --- a/compose/local/django/celery/beat/start +++ b/compose/local/django/celery/beat/start @@ -5,4 +5,6 @@ set -o nounset rm -f './celerybeat.pid' -celery -A core.celery_app beat -l INFO +watchmedo \ + auto-restart --directory=./ --pattern=*.py --recursive -- \ + celery --workdir="/app" -A core.celery_app beat --loglevel=INFO diff --git a/compose/local/django/celery/worker/start b/compose/local/django/celery/worker/start index 5cc526ac..0f039d2e 100644 --- a/compose/local/django/celery/worker/start +++ b/compose/local/django/celery/worker/start @@ -4,4 +4,6 @@ set -o errexit set -o nounset -watchgod celery.__main__.main --args -A core.celery_app worker -l INFO +watchmedo \ + auto-restart --directory=./ --pattern=*.py --recursive -- \ + celery --workdir="/app" -A core.celery_app worker --loglevel=INFO diff --git a/core/settings/local.py b/core/settings/local.py index 2320a6da..ea7710e0 100644 --- a/core/settings/local.py +++ b/core/settings/local.py @@ -35,9 +35,7 @@ # WhiteNoise # ------------------------------------------------------------------------------ # http://whitenoise.evans.io/en/latest/django.html#using-whitenoise-in-development -INSTALLED_APPS = [ - "whitenoise.runserver_nostatic" -] + INSTALLED_APPS # noqa F405 +INSTALLED_APPS = ["whitenoise.runserver_nostatic"] + INSTALLED_APPS # noqa F405 # django-debug-toolbar diff --git a/docker-compose.local.yaml b/docker-compose.local.yaml index ee487a3f..eaac25a6 100644 --- a/docker-compose.local.yaml +++ b/docker-compose.local.yaml @@ -9,8 +9,7 @@ services: build: context: . dockerfile: ./compose/local/django/Dockerfile - image: django - container_name: ayushma_local_django + image: ayushma_local depends_on: - postgres - redis @@ -27,8 +26,7 @@ services: build: context: . dockerfile: ./compose/production/postgres/Dockerfile - image: postgres - container_name: ayushma_local_postgres + image: ayushma_postgres volumes: - ayushma_local_postgres_data:/var/lib/postgresql/data:Z - ayushma_local_postgres_data_backups:/backups:z @@ -37,24 +35,13 @@ services: redis: image: redis:6 - container_name: ayushma_local_redis celeryworker: <<: *django - image: ayushma_local_celeryworker - container_name: ayushma_local_celeryworker - depends_on: - - redis - - postgres ports: [] command: /start-celeryworker celerybeat: <<: *django - image: ayushma_local_celerybeat - container_name: ayushma_local_celerybeat - depends_on: - - redis - - postgres ports: [] command: /start-celerybeat diff --git a/docker-compose.production.yaml b/docker-compose.production.yaml index 8d527675..ef55f10c 100644 --- a/docker-compose.production.yaml +++ b/docker-compose.production.yaml @@ -9,7 +9,7 @@ services: build: context: . dockerfile: ./compose/production/django/Dockerfile - image: ayushma_production_django + image: ayushma_production depends_on: - postgres - redis @@ -24,7 +24,7 @@ services: build: context: . dockerfile: ./compose/production/postgres/Dockerfile - image: ayushma_production_postgres + image: ayushma_postgres volumes: - production_postgres_data:/var/lib/postgresql/data:Z - production_postgres_data_backups:/backups:z @@ -36,12 +36,10 @@ services: celeryworker: <<: *django - image: ayushma_production_celeryworker ports: [] command: /start-celeryworker celerybeat: <<: *django - image: ayushma_production_celerybeat ports: [] command: /start-celerybeat diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 00000000..52ea391e --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,24 @@ +[tool.isort] +profile = "black" +known_third_party = [ + "bs4", + "celery", + "corsheaders", + "django", + "django_filters", + "djangoql", + "drf_spectacular", + "environ", + "google", + "langchain", + "nltk", + "openai", + "pinecone", + "pypdf2", + "requests", + "rest_framework", + "rest_framework_simplejw", + "sentry_sdk", + "simple_history", + "tiktoken" +] diff --git a/setup.cfg b/setup.cfg index 9dcdd6bb..c0b76cdb 100644 --- a/setup.cfg +++ b/setup.cfg @@ -27,7 +27,3 @@ exclude = __pycache__, .venv, migrations, - - -[isort] -profile = black