From 5b343b68cf0acb56da16452a6f5aea5220cf872d Mon Sep 17 00:00:00 2001 From: "Max P." Date: Wed, 30 Apr 2025 15:01:58 +0200 Subject: [PATCH] feat(pyvtt): add CI pipeline and restructure project - Add GitHub Actions workflow for building and publishing packages. - Introduce `pyproject.toml` for project metadata and dependency management. - Remove `requirements.txt` in favor of Poetry for dependency handling. - Restructure source files under `src/pyvtt` for better organization. - Enhance `notify.py` with sound playback and improve error handling. - Update `voice_to_text_tray.py` to support dynamic configuration reload. - Add `.vscode/settings.json` for improved IDE configuration. - Update `.gitignore` to exclude build artifacts. Signed-off-by: Max P. --- .github/workflows/build-and-deploy.yml | 52 ++ .gitignore | 3 +- .vscode/settings.json | 6 + README.md | 19 +- poetry.lock | 769 ++++++++++++++++++ pyproject.toml | 24 + requirements.txt | 2 - src/pyvtt/assets/notification.wav | Bin 0 -> 377934 bytes .../pyvtt/configuration.py | 1 - notify.py => src/pyvtt/notify.py | 22 + send_cmd.py => src/pyvtt/send_cmd.py | 17 +- .../pyvtt/voice_to_text_tray.py | 83 +- 12 files changed, 963 insertions(+), 35 deletions(-) create mode 100644 .github/workflows/build-and-deploy.yml create mode 100644 .vscode/settings.json create mode 100644 poetry.lock create mode 100644 pyproject.toml delete mode 100644 requirements.txt create mode 100644 src/pyvtt/assets/notification.wav rename configuration.py => src/pyvtt/configuration.py (99%) rename notify.py => src/pyvtt/notify.py (52%) rename send_cmd.py => src/pyvtt/send_cmd.py (78%) rename voice_to_text_tray.py => src/pyvtt/voice_to_text_tray.py (74%) diff --git a/.github/workflows/build-and-deploy.yml b/.github/workflows/build-and-deploy.yml new file mode 100644 index 0000000..e06d8a2 --- /dev/null +++ b/.github/workflows/build-and-deploy.yml @@ -0,0 +1,52 @@ +name: Build and Publish + +on: + push: + paths: + - "pyproject.toml" # Nur bei Änderungen an dieser Datei + workflow_dispatch: # Manuelles Anstoßen zulassen + +jobs: + build-and-publish: + runs-on: ubuntu-22.04 + + steps: + - name: Checkout Repository + uses: actions/checkout@v4 + + - name: 🐍 Setup Python + uses: actions/setup-python@v5 + with: + python-version: "3.12" + + - name: 🔄 Restore cache + uses: https://git.0xmax42.io/actions/cache@v2 + with: + keys: | + poetry-v1-${{ runner.os }}-${{ hashFiles('poetry.lock') }} + poetry-v1-${{ runner.os }} + paths: | + ~/.cache/pypoetry + ~/.cache/pip + + - name: Install Poetry + run: | + pip install poetry + + - name: Install Project Dependencies + working-directory: . + run: | + poetry install + + - name: Build Package + working-directory: . + run: | + poetry build + + - name: Publish to Gitea Package Registry + working-directory: . + env: + TWINE_USERNAME: ${{ secrets.TWINE_USERNAME }} + TWINE_PASSWORD: ${{ secrets.TWINE_PASSWORD }} + run: | + poetry run twine upload --repository-url ${{ secrets.TWINE_URL }} dist/* diff --git a/.gitignore b/.gitignore index bb6f581..c2bda16 100644 --- a/.gitignore +++ b/.gitignore @@ -1,2 +1,3 @@ pyvtt.settings.json -__pycache__/ \ No newline at end of file +__pycache__/ +dist/ \ No newline at end of file diff --git a/.vscode/settings.json b/.vscode/settings.json new file mode 100644 index 0000000..0284138 --- /dev/null +++ b/.vscode/settings.json @@ -0,0 +1,6 @@ +{ + "python.envFile": "${workspaceFolder}/.env", + "python.analysis.extraPaths": [ + "src" + ] +} \ No newline at end of file diff --git a/README.md b/README.md index cc1f750..8748973 100644 --- a/README.md +++ b/README.md @@ -7,6 +7,19 @@ Python Voice to Text ### Python +Create a virtual environment and activate it: + +```bash +python3 -m venv venv +source venv/bin/activate +``` + +Install the required Python packages with the `requirements.txt` file: + +```bash +pip install -r requirements.txt +``` + - Python 3.6 or higher - pip - requests @@ -17,4 +30,8 @@ Python Voice to Text - [Whisper.cpp](https://github.com/ggerganov/whisper.cpp) - [ffmpeg](https://ffmpeg.org/) - [notify-send](https://manpages.ubuntu.com/manpages/bionic/man1/notify-send.1.html) -- [ollama](https://ollama.com/) \ No newline at end of file +- [ollama](https://ollama.com/) + +## Copyright + +- The Notification sound: Rasool Asaad from Pixabay \ No newline at end of file diff --git a/poetry.lock b/poetry.lock new file mode 100644 index 0000000..2d0705b --- /dev/null +++ b/poetry.lock @@ -0,0 +1,769 @@ +# This file is automatically @generated by Poetry 2.1.2 and should not be changed by hand. + +[[package]] +name = "certifi" +version = "2025.4.26" +description = "Python package for providing Mozilla's CA Bundle." +optional = false +python-versions = ">=3.6" +groups = ["main", "dev"] +files = [ + {file = "certifi-2025.4.26-py3-none-any.whl", hash = "sha256:30350364dfe371162649852c63336a15c70c6510c2ad5015b21c2345311805f3"}, + {file = "certifi-2025.4.26.tar.gz", hash = "sha256:0a816057ea3cdefcef70270d2c515e4506bbc954f417fa5ade2021213bb8f0c6"}, +] + +[[package]] +name = "cffi" +version = "1.17.1" +description = "Foreign Function Interface for Python calling C code." +optional = false +python-versions = ">=3.8" +groups = ["dev"] +markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and sys_platform == \"linux\" and platform_python_implementation != \"PyPy\"" +files = [ + {file = "cffi-1.17.1-cp310-cp310-macosx_10_9_x86_64.whl", hash = "sha256:df8b1c11f177bc2313ec4b2d46baec87a5f3e71fc8b45dab2ee7cae86d9aba14"}, + {file = "cffi-1.17.1-cp310-cp310-macosx_11_0_arm64.whl", hash = "sha256:8f2cdc858323644ab277e9bb925ad72ae0e67f69e804f4898c070998d50b1a67"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:edae79245293e15384b51f88b00613ba9f7198016a5948b5dddf4917d4d26382"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:45398b671ac6d70e67da8e4224a065cec6a93541bb7aebe1b198a61b58c7b702"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:ad9413ccdeda48c5afdae7e4fa2192157e991ff761e7ab8fdd8926f40b160cc3"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:5da5719280082ac6bd9aa7becb3938dc9f9cbd57fac7d2871717b1feb0902ab6"}, + {file = "cffi-1.17.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:2bb1a08b8008b281856e5971307cc386a8e9c5b625ac297e853d36da6efe9c17"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_aarch64.whl", hash = "sha256:045d61c734659cc045141be4bae381a41d89b741f795af1dd018bfb532fd0df8"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_i686.whl", hash = "sha256:6883e737d7d9e4899a8a695e00ec36bd4e5e4f18fabe0aca0efe0a4b44cdb13e"}, + {file = "cffi-1.17.1-cp310-cp310-musllinux_1_1_x86_64.whl", hash = "sha256:6b8b4a92e1c65048ff98cfe1f735ef8f1ceb72e3d5f0c25fdb12087a23da22be"}, + {file = "cffi-1.17.1-cp310-cp310-win32.whl", hash = "sha256:c9c3d058ebabb74db66e431095118094d06abf53284d9c81f27300d0e0d8bc7c"}, + {file = "cffi-1.17.1-cp310-cp310-win_amd64.whl", hash = "sha256:0f048dcf80db46f0098ccac01132761580d28e28bc0f78ae0d58048063317e15"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a45e3c6913c5b87b3ff120dcdc03f6131fa0065027d0ed7ee6190736a74cd401"}, + {file = "cffi-1.17.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:30c5e0cb5ae493c04c8b42916e52ca38079f1b235c2f8ae5f4527b963c401caf"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f75c7ab1f9e4aca5414ed4d8e5c0e303a34f4421f8a0d47a4d019ceff0ab6af4"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a1ed2dd2972641495a3ec98445e09766f077aee98a1c896dcb4ad0d303628e41"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:46bf43160c1a35f7ec506d254e5c890f3c03648a4dbac12d624e4490a7046cd1"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a24ed04c8ffd54b0729c07cee15a81d964e6fee0e3d4d342a27b020d22959dc6"}, + {file = "cffi-1.17.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:610faea79c43e44c71e1ec53a554553fa22321b65fae24889706c0a84d4ad86d"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:a9b15d491f3ad5d692e11f6b71f7857e7835eb677955c00cc0aefcd0669adaf6"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_i686.whl", hash = "sha256:de2ea4b5833625383e464549fec1bc395c1bdeeb5f25c4a3a82b5a8c756ec22f"}, + {file = "cffi-1.17.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:fc48c783f9c87e60831201f2cce7f3b2e4846bf4d8728eabe54d60700b318a0b"}, + {file = "cffi-1.17.1-cp311-cp311-win32.whl", hash = "sha256:85a950a4ac9c359340d5963966e3e0a94a676bd6245a4b55bc43949eee26a655"}, + {file = "cffi-1.17.1-cp311-cp311-win_amd64.whl", hash = "sha256:caaf0640ef5f5517f49bc275eca1406b0ffa6aa184892812030f04c2abf589a0"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_10_9_x86_64.whl", hash = "sha256:805b4371bf7197c329fcb3ead37e710d1bca9da5d583f5073b799d5c5bd1eee4"}, + {file = "cffi-1.17.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:733e99bc2df47476e3848417c5a4540522f234dfd4ef3ab7fafdf555b082ec0c"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1257bdabf294dceb59f5e70c64a3e2f462c30c7ad68092d01bbbfb1c16b1ba36"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:da95af8214998d77a98cc14e3a3bd00aa191526343078b530ceb0bd710fb48a5"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:d63afe322132c194cf832bfec0dc69a99fb9bb6bbd550f161a49e9e855cc78ff"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:f79fc4fc25f1c8698ff97788206bb3c2598949bfe0fef03d299eb1b5356ada99"}, + {file = "cffi-1.17.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b62ce867176a75d03a665bad002af8e6d54644fad99a3c70905c543130e39d93"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:386c8bf53c502fff58903061338ce4f4950cbdcb23e2902d86c0f722b786bbe3"}, + {file = "cffi-1.17.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:4ceb10419a9adf4460ea14cfd6bc43d08701f0835e979bf821052f1805850fe8"}, + {file = "cffi-1.17.1-cp312-cp312-win32.whl", hash = "sha256:a08d7e755f8ed21095a310a693525137cfe756ce62d066e53f502a83dc550f65"}, + {file = "cffi-1.17.1-cp312-cp312-win_amd64.whl", hash = "sha256:51392eae71afec0d0c8fb1a53b204dbb3bcabcb3c9b807eedf3e1e6ccf2de903"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_10_13_x86_64.whl", hash = "sha256:f3a2b4222ce6b60e2e8b337bb9596923045681d71e5a082783484d845390938e"}, + {file = "cffi-1.17.1-cp313-cp313-macosx_11_0_arm64.whl", hash = "sha256:0984a4925a435b1da406122d4d7968dd861c1385afe3b45ba82b750f229811e2"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d01b12eeeb4427d3110de311e1774046ad344f5b1a7403101878976ecd7a10f3"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:706510fe141c86a69c8ddc029c7910003a17353970cff3b904ff0686a5927683"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:de55b766c7aa2e2a3092c51e0483d700341182f08e67c63630d5b6f200bb28e5"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:c59d6e989d07460165cc5ad3c61f9fd8f1b4796eacbd81cee78957842b834af4"}, + {file = "cffi-1.17.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:dd398dbc6773384a17fe0d3e7eeb8d1a21c2200473ee6806bb5e6a8e62bb73dd"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_aarch64.whl", hash = "sha256:3edc8d958eb099c634dace3c7e16560ae474aa3803a5df240542b305d14e14ed"}, + {file = "cffi-1.17.1-cp313-cp313-musllinux_1_1_x86_64.whl", hash = "sha256:72e72408cad3d5419375fc87d289076ee319835bdfa2caad331e377589aebba9"}, + {file = "cffi-1.17.1-cp313-cp313-win32.whl", hash = "sha256:e03eab0a8677fa80d646b5ddece1cbeaf556c313dcfac435ba11f107ba117b5d"}, + {file = "cffi-1.17.1-cp313-cp313-win_amd64.whl", hash = "sha256:f6a16c31041f09ead72d69f583767292f750d24913dadacf5756b966aacb3f1a"}, + {file = "cffi-1.17.1-cp38-cp38-macosx_10_9_x86_64.whl", hash = "sha256:636062ea65bd0195bc012fea9321aca499c0504409f413dc88af450b57ffd03b"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c7eac2ef9b63c79431bc4b25f1cd649d7f061a28808cbc6c47b534bd789ef964"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e221cf152cff04059d011ee126477f0d9588303eb57e88923578ace7baad17f9"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:31000ec67d4221a71bd3f67df918b1f88f676f1c3b535a7eb473255fdc0b83fc"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:6f17be4345073b0a7b8ea599688f692ac3ef23ce28e5df79c04de519dbc4912c"}, + {file = "cffi-1.17.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0e2b1fac190ae3ebfe37b979cc1ce69c81f4e4fe5746bb401dca63a9062cdaf1"}, + {file = "cffi-1.17.1-cp38-cp38-win32.whl", hash = "sha256:7596d6620d3fa590f677e9ee430df2958d2d6d6de2feeae5b20e82c00b76fbf8"}, + {file = "cffi-1.17.1-cp38-cp38-win_amd64.whl", hash = "sha256:78122be759c3f8a014ce010908ae03364d00a1f81ab5c7f4a7a5120607ea56e1"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_10_9_x86_64.whl", hash = "sha256:b2ab587605f4ba0bf81dc0cb08a41bd1c0a5906bd59243d56bad7668a6fc6c16"}, + {file = "cffi-1.17.1-cp39-cp39-macosx_11_0_arm64.whl", hash = "sha256:28b16024becceed8c6dfbc75629e27788d8a3f9030691a1dbf9821a128b22c36"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_12_i686.manylinux2010_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1d599671f396c4723d016dbddb72fe8e0397082b0a77a4fab8028923bec050e8"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:ca74b8dbe6e8e8263c0ffd60277de77dcee6c837a3d0881d8c1ead7268c9e576"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f7f5baafcc48261359e14bcd6d9bff6d4b28d9103847c9e136694cb0501aef87"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:98e3969bcff97cae1b2def8ba499ea3d6f31ddfdb7635374834cf89a1a08ecf0"}, + {file = "cffi-1.17.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cdf5ce3acdfd1661132f2a9c19cac174758dc2352bfe37d98aa7512c6b7178b3"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_aarch64.whl", hash = "sha256:9755e4345d1ec879e3849e62222a18c7174d65a6a92d5b346b1863912168b595"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_i686.whl", hash = "sha256:f1e22e8c4419538cb197e4dd60acc919d7696e5ef98ee4da4e01d3f8cfa4cc5a"}, + {file = "cffi-1.17.1-cp39-cp39-musllinux_1_1_x86_64.whl", hash = "sha256:c03e868a0b3bc35839ba98e74211ed2b05d2119be4e8a0f224fba9384f1fe02e"}, + {file = "cffi-1.17.1-cp39-cp39-win32.whl", hash = "sha256:e31ae45bc2e29f6b2abd0de1cc3b9d5205aa847cafaecb8af1476a609a2f6eb7"}, + {file = "cffi-1.17.1-cp39-cp39-win_amd64.whl", hash = "sha256:d016c76bdd850f3c626af19b0542c9677ba156e4ee4fccfdd7848803533ef662"}, + {file = "cffi-1.17.1.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, +] + +[package.dependencies] +pycparser = "*" + +[[package]] +name = "charset-normalizer" +version = "3.4.1" +description = "The Real First Universal Charset Detector. Open, modern and actively maintained alternative to Chardet." +optional = false +python-versions = ">=3.7" +groups = ["main", "dev"] +files = [ + {file = "charset_normalizer-3.4.1-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:91b36a978b5ae0ee86c394f5a54d6ef44db1de0815eb43de826d41d21e4af3de"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7461baadb4dc00fd9e0acbe254e3d7d2112e7f92ced2adc96e54ef6501c5f176"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:e218488cd232553829be0664c2292d3af2eeeb94b32bea483cf79ac6a694e037"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:80ed5e856eb7f30115aaf94e4a08114ccc8813e6ed1b5efa74f9f82e8509858f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b010a7a4fd316c3c484d482922d13044979e78d1861f0e0650423144c616a46a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:4532bff1b8421fd0a320463030c7520f56a79c9024a4e88f01c537316019005a"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_aarch64.whl", hash = "sha256:d973f03c0cb71c5ed99037b870f2be986c3c05e63622c017ea9816881d2dd247"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_i686.whl", hash = "sha256:3a3bd0dcd373514dcec91c411ddb9632c0d7d92aed7093b8c3bbb6d69ca74408"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_ppc64le.whl", hash = "sha256:d9c3cdf5390dcd29aa8056d13e8e99526cda0305acc038b96b30352aff5ff2bb"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_s390x.whl", hash = "sha256:2bdfe3ac2e1bbe5b59a1a63721eb3b95fc9b6817ae4a46debbb4e11f6232428d"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-musllinux_1_2_x86_64.whl", hash = "sha256:eab677309cdb30d047996b36d34caeda1dc91149e4fdca0b1a039b3f79d9a807"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win32.whl", hash = "sha256:c0429126cf75e16c4f0ad00ee0eae4242dc652290f940152ca8c75c3a4b6ee8f"}, + {file = "charset_normalizer-3.4.1-cp310-cp310-win_amd64.whl", hash = "sha256:9f0b8b1c6d84c8034a44893aba5e767bf9c7a211e313a9605d9c617d7083829f"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:8bfa33f4f2672964266e940dd22a195989ba31669bd84629f05fab3ef4e2d125"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28bf57629c75e810b6ae989f03c0828d64d6b26a5e205535585f96093e405ed1"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:f08ff5e948271dc7e18a35641d2f11a4cd8dfd5634f55228b691e62b37125eb3"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:234ac59ea147c59ee4da87a0c0f098e9c8d169f4dc2a159ef720f1a61bbe27cd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fd4ec41f914fa74ad1b8304bbc634b3de73d2a0889bd32076342a573e0779e00"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:eea6ee1db730b3483adf394ea72f808b6e18cf3cb6454b4d86e04fa8c4327a12"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:c96836c97b1238e9c9e3fe90844c947d5afbf4f4c92762679acfe19927d81d77"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:4d86f7aff21ee58f26dcf5ae81a9addbd914115cdebcbb2217e4f0ed8982e146"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:09b5e6733cbd160dcc09589227187e242a30a49ca5cefa5a7edd3f9d19ed53fd"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:5777ee0881f9499ed0f71cc82cf873d9a0ca8af166dfa0af8ec4e675b7df48e6"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:237bdbe6159cff53b4f24f397d43c6336c6b0b42affbe857970cefbb620911c8"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win32.whl", hash = "sha256:8417cb1f36cc0bc7eaba8ccb0e04d55f0ee52df06df3ad55259b9a323555fc8b"}, + {file = "charset_normalizer-3.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:d7f50a1f8c450f3925cb367d011448c39239bb3eb4117c36a6d354794de4ce76"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:73d94b58ec7fecbc7366247d3b0b10a21681004153238750bb67bd9012414545"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dad3e487649f498dd991eeb901125411559b22e8d7ab25d3aeb1af367df5efd7"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c30197aa96e8eed02200a83fba2657b4c3acd0f0aa4bdc9f6c1af8e8962e0757"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2369eea1ee4a7610a860d88f268eb39b95cb588acd7235e02fd5a5601773d4fa"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc2722592d8998c870fa4e290c2eec2c1569b87fe58618e67d38b4665dfa680d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:ffc9202a29ab3920fa812879e95a9e78b2465fd10be7fcbd042899695d75e616"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:804a4d582ba6e5b747c625bf1255e6b1507465494a40a2130978bda7b932c90b"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:0f55e69f030f7163dffe9fd0752b32f070566451afe180f99dbeeb81f511ad8d"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c4c3e6da02df6fa1410a7680bd3f63d4f710232d3139089536310d027950696a"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:5df196eb874dae23dcfb968c83d4f8fdccb333330fe1fc278ac5ceeb101003a9"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e358e64305fe12299a08e08978f51fc21fac060dcfcddd95453eabe5b93ed0e1"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win32.whl", hash = "sha256:9b23ca7ef998bc739bf6ffc077c2116917eabcc901f88da1b9856b210ef63f35"}, + {file = "charset_normalizer-3.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:6ff8a4a60c227ad87030d76e99cd1698345d4491638dfa6673027c48b3cd395f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:aabfa34badd18f1da5ec1bc2715cadc8dca465868a4e73a0173466b688f29dda"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:22e14b5d70560b8dd51ec22863f370d1e595ac3d024cb8ad7d308b4cd95f8313"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:8436c508b408b82d87dc5f62496973a1805cd46727c34440b0d29d8a2f50a6c9"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:2d074908e1aecee37a7635990b2c6d504cd4766c7bc9fc86d63f9c09af3fa11b"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:955f8851919303c92343d2f66165294848d57e9bba6cf6e3625485a70a038d11"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ecbf16649486d4aebafeaa7ec4c9fed8b88101f4dd612dcaf65d5e815f837f"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_aarch64.whl", hash = "sha256:0924e81d3d5e70f8126529951dac65c1010cdf117bb75eb02dd12339b57749dd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_i686.whl", hash = "sha256:2967f74ad52c3b98de4c3b32e1a44e32975e008a9cd2a8cc8966d6a5218c5cb2"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_ppc64le.whl", hash = "sha256:c75cb2a3e389853835e84a2d8fb2b81a10645b503eca9bcb98df6b5a43eb8886"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_s390x.whl", hash = "sha256:09b26ae6b1abf0d27570633b2b078a2a20419c99d66fb2823173d73f188ce601"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-musllinux_1_2_x86_64.whl", hash = "sha256:fa88b843d6e211393a37219e6a1c1df99d35e8fd90446f1118f4216e307e48cd"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win32.whl", hash = "sha256:eb8178fe3dba6450a3e024e95ac49ed3400e506fd4e9e5c32d30adda88cbd407"}, + {file = "charset_normalizer-3.4.1-cp313-cp313-win_amd64.whl", hash = "sha256:b1ac5992a838106edb89654e0aebfc24f5848ae2547d22c2c3f66454daa11971"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f30bf9fd9be89ecb2360c7d94a711f00c09b976258846efe40db3d05828e8089"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:97f68b8d6831127e4787ad15e6757232e14e12060bec17091b85eb1486b91d8d"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:7974a0b5ecd505609e3b19742b60cee7aa2aa2fb3151bc917e6e2646d7667dcf"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:fc54db6c8593ef7d4b2a331b58653356cf04f67c960f584edb7c3d8c97e8f39e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:311f30128d7d333eebd7896965bfcfbd0065f1716ec92bd5638d7748eb6f936a"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_aarch64.whl", hash = "sha256:7d053096f67cd1241601111b698f5cad775f97ab25d81567d3f59219b5f1adbd"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_i686.whl", hash = "sha256:807f52c1f798eef6cf26beb819eeb8819b1622ddfeef9d0977a8502d4db6d534"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_ppc64le.whl", hash = "sha256:dccbe65bd2f7f7ec22c4ff99ed56faa1e9f785482b9bbd7c717e26fd723a1d1e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_s390x.whl", hash = "sha256:2fb9bd477fdea8684f78791a6de97a953c51831ee2981f8e4f583ff3b9d9687e"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-musllinux_1_2_x86_64.whl", hash = "sha256:01732659ba9b5b873fc117534143e4feefecf3b2078b0a6a2e925271bb6f4cfa"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win32.whl", hash = "sha256:7a4f97a081603d2050bfaffdefa5b02a9ec823f8348a572e39032caa8404a487"}, + {file = "charset_normalizer-3.4.1-cp37-cp37m-win_amd64.whl", hash = "sha256:7b1bef6280950ee6c177b326508f86cad7ad4dff12454483b51d8b7d673a2c5d"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-macosx_10_9_universal2.whl", hash = "sha256:ecddf25bee22fe4fe3737a399d0d177d72bc22be6913acfab364b40bce1ba83c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:8c60ca7339acd497a55b0ea5d506b2a2612afb2826560416f6894e8b5770d4a9"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b7b2d86dd06bfc2ade3312a83a5c364c7ec2e3498f8734282c6c3d4b07b346b8"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:dd78cfcda14a1ef52584dbb008f7ac81c1328c0f58184bf9a84c49c605002da6"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:6e27f48bcd0957c6d4cb9d6fa6b61d192d0b13d5ef563e5f2ae35feafc0d179c"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:01ad647cdd609225c5350561d084b42ddf732f4eeefe6e678765636791e78b9a"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_aarch64.whl", hash = "sha256:619a609aa74ae43d90ed2e89bdd784765de0a25ca761b93e196d938b8fd1dbbd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_i686.whl", hash = "sha256:89149166622f4db9b4b6a449256291dc87a99ee53151c74cbd82a53c8c2f6ccd"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_ppc64le.whl", hash = "sha256:7709f51f5f7c853f0fb938bcd3bc59cdfdc5203635ffd18bf354f6967ea0f824"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_s390x.whl", hash = "sha256:345b0426edd4e18138d6528aed636de7a9ed169b4aaf9d61a8c19e39d26838ca"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-musllinux_1_2_x86_64.whl", hash = "sha256:0907f11d019260cdc3f94fbdb23ff9125f6b5d1039b76003b5b0ac9d6a6c9d5b"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win32.whl", hash = "sha256:ea0d8d539afa5eb2728aa1932a988a9a7af94f18582ffae4bc10b3fbdad0626e"}, + {file = "charset_normalizer-3.4.1-cp38-cp38-win_amd64.whl", hash = "sha256:329ce159e82018d646c7ac45b01a430369d526569ec08516081727a20e9e4af4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:b97e690a2118911e39b4042088092771b4ae3fc3aa86518f84b8cf6888dbdb41"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:78baa6d91634dfb69ec52a463534bc0df05dbd546209b79a3880a34487f4b84f"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1a2bc9f351a75ef49d664206d51f8e5ede9da246602dc2d2726837620ea034b2"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:75832c08354f595c760a804588b9357d34ec00ba1c940c15e31e96d902093770"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0af291f4fe114be0280cdd29d533696a77b5b49cfde5467176ecab32353395c4"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0167ddc8ab6508fe81860a57dd472b2ef4060e8d378f0cc555707126830f2537"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_aarch64.whl", hash = "sha256:2a75d49014d118e4198bcee5ee0a6f25856b29b12dbf7cd012791f8a6cc5c496"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_i686.whl", hash = "sha256:363e2f92b0f0174b2f8238240a1a30142e3db7b957a5dd5689b0e75fb717cc78"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_ppc64le.whl", hash = "sha256:ab36c8eb7e454e34e60eb55ca5d241a5d18b2c6244f6827a30e451c42410b5f7"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_s390x.whl", hash = "sha256:4c0907b1928a36d5a998d72d64d8eaa7244989f7aaaf947500d3a800c83a3fd6"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-musllinux_1_2_x86_64.whl", hash = "sha256:04432ad9479fa40ec0f387795ddad4437a2b50417c69fa275e212933519ff294"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win32.whl", hash = "sha256:3bed14e9c89dcb10e8f3a29f9ccac4955aebe93c71ae803af79265c9ca5644c5"}, + {file = "charset_normalizer-3.4.1-cp39-cp39-win_amd64.whl", hash = "sha256:49402233c892a461407c512a19435d1ce275543138294f7ef013f0b63d5d3765"}, + {file = "charset_normalizer-3.4.1-py3-none-any.whl", hash = "sha256:d98b1668f06378c6dbefec3b92299716b931cd4e6061f3c875a71ced1780ab85"}, + {file = "charset_normalizer-3.4.1.tar.gz", hash = "sha256:44251f18cd68a75b56585dd00dae26183e102cd5e0f9f1466e6df5da2ed64ea3"}, +] + +[[package]] +name = "cryptography" +version = "44.0.2" +description = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." +optional = false +python-versions = "!=3.9.0,!=3.9.1,>=3.7" +groups = ["dev"] +markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and sys_platform == \"linux\"" +files = [ + {file = "cryptography-44.0.2-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:efcfe97d1b3c79e486554efddeb8f6f53a4cdd4cf6086642784fa31fc384e1d7"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29ecec49f3ba3f3849362854b7253a9f59799e3763b0c9d0826259a88efa02f1"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc821e161ae88bfe8088d11bb39caf2916562e0a2dc7b6d56714a48b784ef0bb"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:3c00b6b757b32ce0f62c574b78b939afab9eecaf597c4d624caca4f9e71e7843"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7bdcd82189759aba3816d1f729ce42ffded1ac304c151d0a8e89b9996ab863d5"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:4973da6ca3db4405c54cd0b26d328be54c7747e89e284fcff166132eb7bccc9c"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:4e389622b6927d8133f314949a9812972711a111d577a5d1f4bee5e58736b80a"}, + {file = "cryptography-44.0.2-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f514ef4cd14bb6fb484b4a60203e912cfcb64f2ab139e88c2274511514bf7308"}, + {file = "cryptography-44.0.2-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:1bc312dfb7a6e5d66082c87c34c8a62176e684b6fe3d90fcfe1568de675e6688"}, + {file = "cryptography-44.0.2-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:3b721b8b4d948b218c88cb8c45a01793483821e709afe5f622861fc6182b20a7"}, + {file = "cryptography-44.0.2-cp37-abi3-win32.whl", hash = "sha256:51e4de3af4ec3899d6d178a8c005226491c27c4ba84101bfb59c901e10ca9f79"}, + {file = "cryptography-44.0.2-cp37-abi3-win_amd64.whl", hash = "sha256:c505d61b6176aaf982c5717ce04e87da5abc9a36a5b39ac03905c4aafe8de7aa"}, + {file = "cryptography-44.0.2-cp39-abi3-macosx_10_9_universal2.whl", hash = "sha256:8e0ddd63e6bf1161800592c71ac794d3fb8001f2caebe0966e77c5234fa9efc3"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:81276f0ea79a208d961c433a947029e1a15948966658cf6710bbabb60fcc2639"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:9a1e657c0f4ea2a23304ee3f964db058c9e9e635cc7019c4aa21c330755ef6fd"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:6210c05941994290f3f7f175a4a57dbbb2afd9273657614c506d5976db061181"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:d1c3572526997b36f245a96a2b1713bf79ce99b271bbcf084beb6b9b075f29ea"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b042d2a275c8cee83a4b7ae30c45a15e6a4baa65a179a0ec2d78ebb90e4f6699"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:d03806036b4f89e3b13b6218fefea8d5312e450935b1a2d55f0524e2ed7c59d9"}, + {file = "cryptography-44.0.2-cp39-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:c7362add18b416b69d58c910caa217f980c5ef39b23a38a0880dfd87bdf8cd23"}, + {file = "cryptography-44.0.2-cp39-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:8cadc6e3b5a1f144a039ea08a0bdb03a2a92e19c46be3285123d32029f40a922"}, + {file = "cryptography-44.0.2-cp39-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:6f101b1f780f7fc613d040ca4bdf835c6ef3b00e9bd7125a4255ec574c7916e4"}, + {file = "cryptography-44.0.2-cp39-abi3-win32.whl", hash = "sha256:3dc62975e31617badc19a906481deacdeb80b4bb454394b4098e3f2525a488c5"}, + {file = "cryptography-44.0.2-cp39-abi3-win_amd64.whl", hash = "sha256:5f6f90b72d8ccadb9c6e311c775c8305381db88374c65fa1a68250aa8a9cb3a6"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-macosx_10_9_x86_64.whl", hash = "sha256:af4ff3e388f2fa7bff9f7f2b31b87d5651c45731d3e8cfa0944be43dff5cfbdb"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:0529b1d5a0105dd3731fa65680b45ce49da4d8115ea76e9da77a875396727b41"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:7ca25849404be2f8e4b3c59483d9d3c51298a22c1c61a0e84415104dacaf5562"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:268e4e9b177c76d569e8a145a6939eca9a5fec658c932348598818acf31ae9a5"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:9eb9d22b0a5d8fd9925a7764a054dca914000607dff201a24c791ff5c799e1fa"}, + {file = "cryptography-44.0.2-pp310-pypy310_pp73-win_amd64.whl", hash = "sha256:2bf7bf75f7df9715f810d1b038870309342bff3069c5bd8c6b96128cb158668d"}, + {file = "cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:909c97ab43a9c0c0b0ada7a1281430e4e5ec0458e6d9244c0e821bbf152f061d"}, + {file = "cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:96e7a5e9d6e71f9f4fca8eebfd603f8e86c5225bb18eb621b2c1e50b290a9471"}, + {file = "cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:d1b3031093a366ac767b3feb8bcddb596671b3aaff82d4050f984da0c248b615"}, + {file = "cryptography-44.0.2-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:04abd71114848aa25edb28e225ab5f268096f44cf0127f3d36975bdf1bdf3390"}, + {file = "cryptography-44.0.2.tar.gz", hash = "sha256:c63454aa261a0cf0c5b4718349629793e9e634993538db841165b3df74f37ec0"}, +] + +[package.dependencies] +cffi = {version = ">=1.12", markers = "platform_python_implementation != \"PyPy\""} + +[package.extras] +docs = ["sphinx (>=5.3.0)", "sphinx-rtd-theme (>=3.0.0) ; python_version >= \"3.8\""] +docstest = ["pyenchant (>=3)", "readme-renderer (>=30.0)", "sphinxcontrib-spelling (>=7.3.1)"] +nox = ["nox (>=2024.4.15)", "nox[uv] (>=2024.3.2) ; python_version >= \"3.8\""] +pep8test = ["check-sdist ; python_version >= \"3.8\"", "click (>=8.0.1)", "mypy (>=1.4)", "ruff (>=0.3.6)"] +sdist = ["build (>=1.0.0)"] +ssh = ["bcrypt (>=3.1.5)"] +test = ["certifi (>=2024)", "cryptography-vectors (==44.0.2)", "pretend (>=0.7)", "pytest (>=7.4.0)", "pytest-benchmark (>=4.0)", "pytest-cov (>=2.10.1)", "pytest-xdist (>=3.5.0)"] +test-randomorder = ["pytest-randomly"] + +[[package]] +name = "docutils" +version = "0.21.2" +description = "Docutils -- Python Documentation Utilities" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "docutils-0.21.2-py3-none-any.whl", hash = "sha256:dafca5b9e384f0e419294eb4d2ff9fa826435bf15f15b7bd45723e8ad76811b2"}, + {file = "docutils-0.21.2.tar.gz", hash = "sha256:3a6b18732edf182daa3cd12775bbb338cf5691468f91eeeb109deff6ebfa986f"}, +] + +[[package]] +name = "id" +version = "1.5.0" +description = "A tool for generating OIDC identities" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "id-1.5.0-py3-none-any.whl", hash = "sha256:f1434e1cef91f2cbb8a4ec64663d5a23b9ed43ef44c4c957d02583d61714c658"}, + {file = "id-1.5.0.tar.gz", hash = "sha256:292cb8a49eacbbdbce97244f47a97b4c62540169c976552e497fd57df0734c1d"}, +] + +[package.dependencies] +requests = "*" + +[package.extras] +dev = ["build", "bump (>=1.3.2)", "id[lint,test]"] +lint = ["bandit", "interrogate", "mypy", "ruff (<0.8.2)", "types-requests"] +test = ["coverage[toml]", "pretend", "pytest", "pytest-cov"] + +[[package]] +name = "idna" +version = "3.10" +description = "Internationalized Domain Names in Applications (IDNA)" +optional = false +python-versions = ">=3.6" +groups = ["main", "dev"] +files = [ + {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, + {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, +] + +[package.extras] +all = ["flake8 (>=7.1.1)", "mypy (>=1.11.2)", "pytest (>=8.3.2)", "ruff (>=0.6.2)"] + +[[package]] +name = "jaraco-classes" +version = "3.4.0" +description = "Utility functions for Python class constructs" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\"" +files = [ + {file = "jaraco.classes-3.4.0-py3-none-any.whl", hash = "sha256:f662826b6bed8cace05e7ff873ce0f9283b5c924470fe664fff1c2f00f581790"}, + {file = "jaraco.classes-3.4.0.tar.gz", hash = "sha256:47a024b51d0239c0dd8c8540c6c7f484be3b8fcf0b2d85c13825780d3b3f3acd"}, +] + +[package.dependencies] +more-itertools = "*" + +[package.extras] +docs = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +testing = ["pytest (>=6)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1)"] + +[[package]] +name = "jaraco-context" +version = "6.0.1" +description = "Useful decorators and context managers" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\"" +files = [ + {file = "jaraco.context-6.0.1-py3-none-any.whl", hash = "sha256:f797fc481b490edb305122c9181830a3a5b76d84ef6d1aef2fb9b47ab956f9e4"}, + {file = "jaraco_context-6.0.1.tar.gz", hash = "sha256:9bae4ea555cf0b14938dc0aee7c9f32ed303aa20a3b73e7dc80111628792d1b3"}, +] + +[package.extras] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +test = ["portend", "pytest (>=6,!=8.1.*)", "pytest-checkdocs (>=2.4)", "pytest-cov", "pytest-enabler (>=2.2)", "pytest-mypy", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] + +[[package]] +name = "jaraco-functools" +version = "4.1.0" +description = "Functools like those found in stdlib" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\"" +files = [ + {file = "jaraco.functools-4.1.0-py3-none-any.whl", hash = "sha256:ad159f13428bc4acbf5541ad6dec511f91573b90fba04df61dafa2a1231cf649"}, + {file = "jaraco_functools-4.1.0.tar.gz", hash = "sha256:70f7e0e2ae076498e212562325e805204fc092d7b4c17e0e86c959e249701a9d"}, +] + +[package.dependencies] +more-itertools = "*" + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["jaraco.classes", "pytest (>=6,!=8.1.*)"] +type = ["pytest-mypy"] + +[[package]] +name = "jeepney" +version = "0.9.0" +description = "Low-level, pure Python DBus protocol wrapper." +optional = false +python-versions = ">=3.7" +groups = ["dev"] +markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and sys_platform == \"linux\"" +files = [ + {file = "jeepney-0.9.0-py3-none-any.whl", hash = "sha256:97e5714520c16fc0a45695e5365a2e11b81ea79bba796e26f9f1d178cb182683"}, + {file = "jeepney-0.9.0.tar.gz", hash = "sha256:cf0e9e845622b81e4a28df94c40345400256ec608d0e55bb8a3feaa9163f5732"}, +] + +[package.extras] +test = ["async-timeout ; python_version < \"3.11\"", "pytest", "pytest-asyncio (>=0.17)", "pytest-trio", "testpath", "trio"] +trio = ["trio"] + +[[package]] +name = "keyring" +version = "25.6.0" +description = "Store and access your passwords safely." +optional = false +python-versions = ">=3.9" +groups = ["dev"] +markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\"" +files = [ + {file = "keyring-25.6.0-py3-none-any.whl", hash = "sha256:552a3f7af126ece7ed5c89753650eec89c7eaae8617d0aa4d9ad2b75111266bd"}, + {file = "keyring-25.6.0.tar.gz", hash = "sha256:0b39998aa941431eb3d9b0d4b2460bc773b9df6fed7621c2dfb291a7e0187a66"}, +] + +[package.dependencies] +"jaraco.classes" = "*" +"jaraco.context" = "*" +"jaraco.functools" = "*" +jeepney = {version = ">=0.4.2", markers = "sys_platform == \"linux\""} +pywin32-ctypes = {version = ">=0.2.0", markers = "sys_platform == \"win32\""} +SecretStorage = {version = ">=3.2", markers = "sys_platform == \"linux\""} + +[package.extras] +check = ["pytest-checkdocs (>=2.4)", "pytest-ruff (>=0.2.1) ; sys_platform != \"cygwin\""] +completion = ["shtab (>=1.1.0)"] +cover = ["pytest-cov"] +doc = ["furo", "jaraco.packaging (>=9.3)", "jaraco.tidelift (>=1.4)", "rst.linker (>=1.9)", "sphinx (>=3.5)", "sphinx-lint"] +enabler = ["pytest-enabler (>=2.2)"] +test = ["pyfakefs", "pytest (>=6,!=8.1.*)"] +type = ["pygobject-stubs", "pytest-mypy", "shtab", "types-pywin32"] + +[[package]] +name = "markdown-it-py" +version = "3.0.0" +description = "Python port of markdown-it. Markdown parsing, done right!" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "markdown-it-py-3.0.0.tar.gz", hash = "sha256:e3f60a94fa066dc52ec76661e37c851cb232d92f9886b15cb560aaada2df8feb"}, + {file = "markdown_it_py-3.0.0-py3-none-any.whl", hash = "sha256:355216845c60bd96232cd8d8c40e8f9765cc86f46880e43a8fd22dc1a1a8cab1"}, +] + +[package.dependencies] +mdurl = ">=0.1,<1.0" + +[package.extras] +benchmarking = ["psutil", "pytest", "pytest-benchmark"] +code-style = ["pre-commit (>=3.0,<4.0)"] +compare = ["commonmark (>=0.9,<1.0)", "markdown (>=3.4,<4.0)", "mistletoe (>=1.0,<2.0)", "mistune (>=2.0,<3.0)", "panflute (>=2.3,<3.0)"] +linkify = ["linkify-it-py (>=1,<3)"] +plugins = ["mdit-py-plugins"] +profiling = ["gprof2dot"] +rtd = ["jupyter_sphinx", "mdit-py-plugins", "myst-parser", "pyyaml", "sphinx", "sphinx-copybutton", "sphinx-design", "sphinx_book_theme"] +testing = ["coverage", "pytest", "pytest-cov", "pytest-regressions"] + +[[package]] +name = "mdurl" +version = "0.1.2" +description = "Markdown URL utilities" +optional = false +python-versions = ">=3.7" +groups = ["dev"] +files = [ + {file = "mdurl-0.1.2-py3-none-any.whl", hash = "sha256:84008a41e51615a49fc9966191ff91509e3c40b939176e643fd50a5c2196b8f8"}, + {file = "mdurl-0.1.2.tar.gz", hash = "sha256:bb413d29f5eea38f31dd4754dd7377d4465116fb207585f97bf925588687c1ba"}, +] + +[[package]] +name = "more-itertools" +version = "10.7.0" +description = "More routines for operating on iterables, beyond itertools" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\"" +files = [ + {file = "more_itertools-10.7.0-py3-none-any.whl", hash = "sha256:d43980384673cb07d2f7d2d918c616b30c659c089ee23953f601d6609c67510e"}, + {file = "more_itertools-10.7.0.tar.gz", hash = "sha256:9fddd5403be01a94b204faadcff459ec3568cf110265d3c54323e1e866ad29d3"}, +] + +[[package]] +name = "nh3" +version = "0.2.21" +description = "Python binding to Ammonia HTML sanitizer Rust crate" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "nh3-0.2.21-cp313-cp313t-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:fcff321bd60c6c5c9cb4ddf2554e22772bb41ebd93ad88171bbbb6f271255286"}, + {file = "nh3-0.2.21-cp313-cp313t-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:31eedcd7d08b0eae28ba47f43fd33a653b4cdb271d64f1aeda47001618348fde"}, + {file = "nh3-0.2.21-cp313-cp313t-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:d426d7be1a2f3d896950fe263332ed1662f6c78525b4520c8e9861f8d7f0d243"}, + {file = "nh3-0.2.21-cp313-cp313t-musllinux_1_2_aarch64.whl", hash = "sha256:9d67709bc0d7d1f5797b21db26e7a8b3d15d21c9c5f58ccfe48b5328483b685b"}, + {file = "nh3-0.2.21-cp313-cp313t-musllinux_1_2_armv7l.whl", hash = "sha256:55823c5ea1f6b267a4fad5de39bc0524d49a47783e1fe094bcf9c537a37df251"}, + {file = "nh3-0.2.21-cp313-cp313t-musllinux_1_2_i686.whl", hash = "sha256:818f2b6df3763e058efa9e69677b5a92f9bc0acff3295af5ed013da544250d5b"}, + {file = "nh3-0.2.21-cp313-cp313t-musllinux_1_2_x86_64.whl", hash = "sha256:b3b5c58161e08549904ac4abd450dacd94ff648916f7c376ae4b2c0652b98ff9"}, + {file = "nh3-0.2.21-cp313-cp313t-win32.whl", hash = "sha256:637d4a10c834e1b7d9548592c7aad760611415fcd5bd346f77fd8a064309ae6d"}, + {file = "nh3-0.2.21-cp313-cp313t-win_amd64.whl", hash = "sha256:713d16686596e556b65e7f8c58328c2df63f1a7abe1277d87625dcbbc012ef82"}, + {file = "nh3-0.2.21-cp38-abi3-macosx_10_12_x86_64.macosx_11_0_arm64.macosx_10_12_universal2.whl", hash = "sha256:a772dec5b7b7325780922dd904709f0f5f3a79fbf756de5291c01370f6df0967"}, + {file = "nh3-0.2.21-cp38-abi3-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:d002b648592bf3033adfd875a48f09b8ecc000abd7f6a8769ed86b6ccc70c759"}, + {file = "nh3-0.2.21-cp38-abi3-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:2a5174551f95f2836f2ad6a8074560f261cf9740a48437d6151fd2d4d7d617ab"}, + {file = "nh3-0.2.21-cp38-abi3-manylinux_2_17_ppc64.manylinux2014_ppc64.whl", hash = "sha256:b8d55ea1fc7ae3633d758a92aafa3505cd3cc5a6e40470c9164d54dff6f96d42"}, + {file = "nh3-0.2.21-cp38-abi3-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:6ae319f17cd8960d0612f0f0ddff5a90700fa71926ca800e9028e7851ce44a6f"}, + {file = "nh3-0.2.21-cp38-abi3-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63ca02ac6f27fc80f9894409eb61de2cb20ef0a23740c7e29f9ec827139fa578"}, + {file = "nh3-0.2.21-cp38-abi3-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a5f77e62aed5c4acad635239ac1290404c7e940c81abe561fd2af011ff59f585"}, + {file = "nh3-0.2.21-cp38-abi3-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:087ffadfdcd497658c3adc797258ce0f06be8a537786a7217649fc1c0c60c293"}, + {file = "nh3-0.2.21-cp38-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:ac7006c3abd097790e611fe4646ecb19a8d7f2184b882f6093293b8d9b887431"}, + {file = "nh3-0.2.21-cp38-abi3-musllinux_1_2_armv7l.whl", hash = "sha256:6141caabe00bbddc869665b35fc56a478eb774a8c1dfd6fba9fe1dfdf29e6efa"}, + {file = "nh3-0.2.21-cp38-abi3-musllinux_1_2_i686.whl", hash = "sha256:20979783526641c81d2f5bfa6ca5ccca3d1e4472474b162c6256745fbfe31cd1"}, + {file = "nh3-0.2.21-cp38-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:a7ea28cd49293749d67e4fcf326c554c83ec912cd09cd94aa7ec3ab1921c8283"}, + {file = "nh3-0.2.21-cp38-abi3-win32.whl", hash = "sha256:6c9c30b8b0d291a7c5ab0967ab200598ba33208f754f2f4920e9343bdd88f79a"}, + {file = "nh3-0.2.21-cp38-abi3-win_amd64.whl", hash = "sha256:bb0014948f04d7976aabae43fcd4cb7f551f9f8ce785a4c9ef66e6c2590f8629"}, + {file = "nh3-0.2.21.tar.gz", hash = "sha256:4990e7ee6a55490dbf00d61a6f476c9a3258e31e711e13713b2ea7d6616f670e"}, +] + +[[package]] +name = "packaging" +version = "25.0" +description = "Core utilities for Python packages" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "packaging-25.0-py3-none-any.whl", hash = "sha256:29572ef2b1f17581046b3a2227d5c611fb25ec70ca1ba8554b24b0e69331a484"}, + {file = "packaging-25.0.tar.gz", hash = "sha256:d443872c98d677bf60f6a1f2f8c1cb748e8fe762d2bf9d3148b5599295b0fc4f"}, +] + +[[package]] +name = "pycparser" +version = "2.22" +description = "C parser in Python" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and sys_platform == \"linux\" and platform_python_implementation != \"PyPy\"" +files = [ + {file = "pycparser-2.22-py3-none-any.whl", hash = "sha256:c3702b6d3dd8c7abc1afa565d7e63d53a1d0bd86cdc24edd75470f4de499cfcc"}, + {file = "pycparser-2.22.tar.gz", hash = "sha256:491c8be9c040f5390f5bf44a5b07752bd07f56edf992381b05c701439eec10f6"}, +] + +[[package]] +name = "pygments" +version = "2.19.1" +description = "Pygments is a syntax highlighting package written in Python." +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "pygments-2.19.1-py3-none-any.whl", hash = "sha256:9ea1544ad55cecf4b8242fab6dd35a93bbce657034b0611ee383099054ab6d8c"}, + {file = "pygments-2.19.1.tar.gz", hash = "sha256:61c16d2a8576dc0649d9f39e089b5f02bcd27fba10d8fb4dcc28173f7a45151f"}, +] + +[package.extras] +windows-terminal = ["colorama (>=0.4.6)"] + +[[package]] +name = "pyqt5" +version = "5.15.11" +description = "Python bindings for the Qt cross platform application toolkit" +optional = false +python-versions = ">=3.8" +groups = ["main"] +files = [ + {file = "PyQt5-5.15.11-cp38-abi3-macosx_11_0_arm64.whl", hash = "sha256:c8b03dd9380bb13c804f0bdb0f4956067f281785b5e12303d529f0462f9afdc2"}, + {file = "PyQt5-5.15.11-cp38-abi3-macosx_11_0_x86_64.whl", hash = "sha256:6cd75628f6e732b1ffcfe709ab833a0716c0445d7aec8046a48d5843352becb6"}, + {file = "PyQt5-5.15.11-cp38-abi3-manylinux_2_17_x86_64.whl", hash = "sha256:cd672a6738d1ae33ef7d9efa8e6cb0a1525ecf53ec86da80a9e1b6ec38c8d0f1"}, + {file = "PyQt5-5.15.11-cp38-abi3-win32.whl", hash = "sha256:76be0322ceda5deecd1708a8d628e698089a1cea80d1a49d242a6d579a40babd"}, + {file = "PyQt5-5.15.11-cp38-abi3-win_amd64.whl", hash = "sha256:bdde598a3bb95022131a5c9ea62e0a96bd6fb28932cc1619fd7ba211531b7517"}, + {file = "PyQt5-5.15.11.tar.gz", hash = "sha256:fda45743ebb4a27b4b1a51c6d8ef455c4c1b5d610c90d2934c7802b5c1557c52"}, +] + +[package.dependencies] +PyQt5-Qt5 = ">=5.15.2,<5.16.0" +PyQt5-sip = ">=12.15,<13" + +[[package]] +name = "pyqt5-qt5" +version = "5.15.16" +description = "The subset of a Qt installation needed by PyQt5." +optional = false +python-versions = "*" +groups = ["main"] +files = [ + {file = "PyQt5_Qt5-5.15.16-1-py3-none-manylinux2014_x86_64.whl", hash = "sha256:2cfa8f50dd29618ef98f29355f83d8a5f3e41003be22128e9b5d94d214b6b468"}, + {file = "PyQt5_Qt5-5.15.16-py3-none-macosx_10_13_x86_64.whl", hash = "sha256:18b6fec012de60921fcb131cf2a21368171dc29050d43e4b81a64be407a36105"}, + {file = "PyQt5_Qt5-5.15.16-py3-none-macosx_11_0_arm64.whl", hash = "sha256:e1a0e7ae35a7615c74a293705204579650930486a89af23082462f429dae504a"}, + {file = "PyQt5_Qt5-5.15.16-py3-none-manylinux2014_x86_64.whl", hash = "sha256:5ee1754a6460849cba76c0f0c490c0ccc3b514abc780b141cf772db22b76b54b"}, +] + +[[package]] +name = "pyqt5-sip" +version = "12.17.0" +description = "The sip module support for PyQt5" +optional = false +python-versions = ">=3.9" +groups = ["main"] +files = [ + {file = "PyQt5_sip-12.17.0-cp310-cp310-macosx_10_9_universal2.whl", hash = "sha256:ec47914cc751608e587c1c2fdabeaf4af7fdc28b9f62796c583bea01c1a1aa3e"}, + {file = "PyQt5_sip-12.17.0-cp310-cp310-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:2f2a8dcc7626fe0da73a0918e05ce2460c7a14ddc946049310e6e35052105434"}, + {file = "PyQt5_sip-12.17.0-cp310-cp310-win32.whl", hash = "sha256:0c75d28b8282be3c1d7dbc76950d6e6eba1e334783224e9b9835ce1a9c64f482"}, + {file = "PyQt5_sip-12.17.0-cp310-cp310-win_amd64.whl", hash = "sha256:8c4bc535bae0dfa764e8534e893619fe843ce5a2e25f901c439bcb960114f686"}, + {file = "PyQt5_sip-12.17.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:2c912807dd638644168ea8c7a447bfd9d85a19471b98c2c588c4d2e911c09b0a"}, + {file = "PyQt5_sip-12.17.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:71514a7d43b44faa1d65a74ad2c5da92c03a251bdc749f009c313f06cceacc9a"}, + {file = "PyQt5_sip-12.17.0-cp311-cp311-win32.whl", hash = "sha256:023466ae96f72fbb8419b44c3f97475de6642fa5632520d0f50fc1a52a3e8200"}, + {file = "PyQt5_sip-12.17.0-cp311-cp311-win_amd64.whl", hash = "sha256:fb565469d08dcb0a427def0c45e722323beb62db79454260482b6948bfd52d47"}, + {file = "PyQt5_sip-12.17.0-cp312-cp312-macosx_10_9_universal2.whl", hash = "sha256:ea08341c8a5da00c81df0d689ecd4ee47a95e1ecad9e362581c92513f2068005"}, + {file = "PyQt5_sip-12.17.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:4a92478d6808040fbe614bb61500fbb3f19f72714b99369ec28d26a7e3494115"}, + {file = "PyQt5_sip-12.17.0-cp312-cp312-win32.whl", hash = "sha256:b0ff280b28813e9bfd3a4de99490739fc29b776dc48f1c849caca7239a10fc8b"}, + {file = "PyQt5_sip-12.17.0-cp312-cp312-win_amd64.whl", hash = "sha256:54c31de7706d8a9a8c0fc3ea2c70468aba54b027d4974803f8eace9c22aad41c"}, + {file = "PyQt5_sip-12.17.0-cp313-cp313-macosx_10_13_universal2.whl", hash = "sha256:c7a7ff355e369616b6bcb41d45b742327c104b2bf1674ec79b8d67f8f2fa9543"}, + {file = "PyQt5_sip-12.17.0-cp313-cp313-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:419b9027e92b0b707632c370cfc6dc1f3b43c6313242fc4db57a537029bd179c"}, + {file = "PyQt5_sip-12.17.0-cp313-cp313-win32.whl", hash = "sha256:351beab964a19f5671b2a3e816ecf4d3543a99a7e0650f88a947fea251a7589f"}, + {file = "PyQt5_sip-12.17.0-cp313-cp313-win_amd64.whl", hash = "sha256:672c209d05661fab8e17607c193bf43991d268a1eefbc2c4551fbf30fd8bb2ca"}, + {file = "PyQt5_sip-12.17.0-cp39-cp39-macosx_10_9_universal2.whl", hash = "sha256:d65a9c1b4cbbd8e856254609f56e897d2cb5c903f77b75fb720cb3a32c76b92b"}, + {file = "PyQt5_sip-12.17.0-cp39-cp39-manylinux_2_5_x86_64.manylinux1_x86_64.whl", hash = "sha256:32b03e7e77ecd7b4119eba486b0706fa59b490bcceb585f9b6ddec8a582082db"}, + {file = "PyQt5_sip-12.17.0-cp39-cp39-win32.whl", hash = "sha256:5b6c734f4ad28f3defac4890ed747d391d246af279200935d49953bc7d915b8c"}, + {file = "PyQt5_sip-12.17.0-cp39-cp39-win_amd64.whl", hash = "sha256:855e8f5787d57e26a48d8c3de1220a8e92ab83be8d73966deac62fdae03ea2f9"}, + {file = "pyqt5_sip-12.17.0.tar.gz", hash = "sha256:682dadcdbd2239af9fdc0c0628e2776b820e128bec88b49b8d692fe682f90b4f"}, +] + +[[package]] +name = "pywin32-ctypes" +version = "0.2.3" +description = "A (partial) reimplementation of pywin32 using ctypes/cffi" +optional = false +python-versions = ">=3.6" +groups = ["dev"] +markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and sys_platform == \"win32\"" +files = [ + {file = "pywin32-ctypes-0.2.3.tar.gz", hash = "sha256:d162dc04946d704503b2edc4d55f3dba5c1d539ead017afa00142c38b9885755"}, + {file = "pywin32_ctypes-0.2.3-py3-none-any.whl", hash = "sha256:8a1513379d709975552d202d942d9837758905c8d01eb82b8bcc30918929e7b8"}, +] + +[[package]] +name = "readme-renderer" +version = "44.0" +description = "readme_renderer is a library for rendering readme descriptions for Warehouse" +optional = false +python-versions = ">=3.9" +groups = ["dev"] +files = [ + {file = "readme_renderer-44.0-py3-none-any.whl", hash = "sha256:2fbca89b81a08526aadf1357a8c2ae889ec05fb03f5da67f9769c9a592166151"}, + {file = "readme_renderer-44.0.tar.gz", hash = "sha256:8712034eabbfa6805cacf1402b4eeb2a73028f72d1166d6f5cb7f9c047c5d1e1"}, +] + +[package.dependencies] +docutils = ">=0.21.2" +nh3 = ">=0.2.14" +Pygments = ">=2.5.1" + +[package.extras] +md = ["cmarkgfm (>=0.8.0)"] + +[[package]] +name = "requests" +version = "2.32.3" +description = "Python HTTP for Humans." +optional = false +python-versions = ">=3.8" +groups = ["main", "dev"] +files = [ + {file = "requests-2.32.3-py3-none-any.whl", hash = "sha256:70761cfe03c773ceb22aa2f671b4757976145175cdfca038c02654d061d6dcc6"}, + {file = "requests-2.32.3.tar.gz", hash = "sha256:55365417734eb18255590a9ff9eb97e9e1da868d4ccd6402399eaf68af20a760"}, +] + +[package.dependencies] +certifi = ">=2017.4.17" +charset-normalizer = ">=2,<4" +idna = ">=2.5,<4" +urllib3 = ">=1.21.1,<3" + +[package.extras] +socks = ["PySocks (>=1.5.6,!=1.5.7)"] +use-chardet-on-py3 = ["chardet (>=3.0.2,<6)"] + +[[package]] +name = "requests-toolbelt" +version = "1.0.0" +description = "A utility belt for advanced users of python-requests" +optional = false +python-versions = ">=2.7, !=3.0.*, !=3.1.*, !=3.2.*, !=3.3.*" +groups = ["dev"] +files = [ + {file = "requests-toolbelt-1.0.0.tar.gz", hash = "sha256:7681a0a3d047012b5bdc0ee37d7f8f07ebe76ab08caeccfc3921ce23c88d5bc6"}, + {file = "requests_toolbelt-1.0.0-py2.py3-none-any.whl", hash = "sha256:cccfdd665f0a24fcf4726e690f65639d272bb0637b9b92dfd91a5568ccf6bd06"}, +] + +[package.dependencies] +requests = ">=2.0.1,<3.0.0" + +[[package]] +name = "rfc3986" +version = "2.0.0" +description = "Validating URI References per RFC 3986" +optional = false +python-versions = ">=3.7" +groups = ["dev"] +files = [ + {file = "rfc3986-2.0.0-py2.py3-none-any.whl", hash = "sha256:50b1502b60e289cb37883f3dfd34532b8873c7de9f49bb546641ce9cbd256ebd"}, + {file = "rfc3986-2.0.0.tar.gz", hash = "sha256:97aacf9dbd4bfd829baad6e6309fa6573aaf1be3f6fa735c8ab05e46cecb261c"}, +] + +[package.extras] +idna2008 = ["idna"] + +[[package]] +name = "rich" +version = "14.0.0" +description = "Render rich text, tables, progress bars, syntax highlighting, markdown and more to the terminal" +optional = false +python-versions = ">=3.8.0" +groups = ["dev"] +files = [ + {file = "rich-14.0.0-py3-none-any.whl", hash = "sha256:1c9491e1951aac09caffd42f448ee3d04e58923ffe14993f6e83068dc395d7e0"}, + {file = "rich-14.0.0.tar.gz", hash = "sha256:82f1bc23a6a21ebca4ae0c45af9bdbc492ed20231dcb63f297d6d1021a9d5725"}, +] + +[package.dependencies] +markdown-it-py = ">=2.2.0" +pygments = ">=2.13.0,<3.0.0" + +[package.extras] +jupyter = ["ipywidgets (>=7.5.1,<9)"] + +[[package]] +name = "secretstorage" +version = "3.3.3" +description = "Python bindings to FreeDesktop.org Secret Service API" +optional = false +python-versions = ">=3.6" +groups = ["dev"] +markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\" and sys_platform == \"linux\"" +files = [ + {file = "SecretStorage-3.3.3-py3-none-any.whl", hash = "sha256:f356e6628222568e3af06f2eba8df495efa13b3b63081dafd4f7d9a7b7bc9f99"}, + {file = "SecretStorage-3.3.3.tar.gz", hash = "sha256:2403533ef369eca6d2ba81718576c5e0f564d5cca1b58f73a8b23e7d4eeebd77"}, +] + +[package.dependencies] +cryptography = ">=2.0" +jeepney = ">=0.6" + +[[package]] +name = "twine" +version = "6.1.0" +description = "Collection of utilities for publishing packages on PyPI" +optional = false +python-versions = ">=3.8" +groups = ["dev"] +files = [ + {file = "twine-6.1.0-py3-none-any.whl", hash = "sha256:a47f973caf122930bf0fbbf17f80b83bc1602c9ce393c7845f289a3001dc5384"}, + {file = "twine-6.1.0.tar.gz", hash = "sha256:be324f6272eff91d07ee93f251edf232fc647935dd585ac003539b42404a8dbd"}, +] + +[package.dependencies] +id = "*" +keyring = {version = ">=15.1", markers = "platform_machine != \"ppc64le\" and platform_machine != \"s390x\""} +packaging = ">=24.0" +readme-renderer = ">=35.0" +requests = ">=2.20" +requests-toolbelt = ">=0.8.0,<0.9.0 || >0.9.0" +rfc3986 = ">=1.4.0" +rich = ">=12.0.0" +urllib3 = ">=1.26.0" + +[package.extras] +keyring = ["keyring (>=15.1)"] + +[[package]] +name = "urllib3" +version = "2.4.0" +description = "HTTP library with thread-safe connection pooling, file post, and more." +optional = false +python-versions = ">=3.9" +groups = ["main", "dev"] +files = [ + {file = "urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813"}, + {file = "urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466"}, +] + +[package.extras] +brotli = ["brotli (>=1.0.9) ; platform_python_implementation == \"CPython\"", "brotlicffi (>=0.8.0) ; platform_python_implementation != \"CPython\""] +h2 = ["h2 (>=4,<5)"] +socks = ["pysocks (>=1.5.6,!=1.5.7,<2.0)"] +zstd = ["zstandard (>=0.18.0)"] + +[metadata] +lock-version = "2.1" +python-versions = ">=3.12" +content-hash = "33d6dddddf6b4c9ff020272b1e39c87ac4b85a53683a2929b7e0673ef4a09e0b" diff --git a/pyproject.toml b/pyproject.toml new file mode 100644 index 0000000..eb09339 --- /dev/null +++ b/pyproject.toml @@ -0,0 +1,24 @@ +[project] +name = "pyvtt" +version = "0.1.0" +description = "Python Voice to Text + LLMA" +authors = [{ name = "Max P.", email = "Mail@MPassarello.de" }] +license = { text = "MIT" } +readme = "README.md" +requires-python = ">=3.12" +dependencies = ["pyqt5 (>=5.15.11,<6.0.0)", "requests (>=2.32.3,<3.0.0)"] + +[tool.poetry] +packages = [{ include = "pyvtt", from = "src" }] +include = ["pyvtt/assets/notification.wav"] + +[tool.poetry.group.dev.dependencies] +twine = "^6.1.0" + +[tool.poetry.scripts] +pyvtt-cmd = "pyvtt.send_cmd:main" +pyvtt-deamon = "pyvtt.voice_to_text_tray:main" + +[build-system] +requires = ["poetry-core>=2.0.0,<3.0.0"] +build-backend = "poetry.core.masonry.api" diff --git a/requirements.txt b/requirements.txt deleted file mode 100644 index e36e09e..0000000 --- a/requirements.txt +++ /dev/null @@ -1,2 +0,0 @@ -requests -PyQt5 diff --git a/src/pyvtt/assets/notification.wav b/src/pyvtt/assets/notification.wav new file mode 100644 index 0000000000000000000000000000000000000000..ebe0234bde9d045e9397dbeec6bf4b4acf8e4025 GIT binary patch literal 377934 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 None: """ @@ -19,4 +20,25 @@ def notify(title: str, message: str) -> None: subprocess.run(["notify-send", "-a", "Voice to Text", "-i", "audio-input-microphone", title, message], check=True) except subprocess.CalledProcessError as e: print("Fehler beim Benachrichtigen mit 'notify-send'.") + print(e) + +def play_sound() -> None: + """ + Plays a sound file using the `paplay` command. + + Args: + sound_file (str): The path to the sound file to be played. + + Raises: + subprocess.CalledProcessError: If the `paplay` command fails. + + Note: + This function requires the `paplay` command to be available on the system. + It is typically available on Linux systems with PulseAudio installed. + """ + sound_file = files("pyvtt.assets").joinpath("notification.wav") + try: + subprocess.run(["paplay", str(sound_file)], check=True) + except subprocess.CalledProcessError as e: + print("Fehler beim Abspielen des Sounds mit 'paplay'.") print(e) \ No newline at end of file diff --git a/send_cmd.py b/src/pyvtt/send_cmd.py similarity index 78% rename from send_cmd.py rename to src/pyvtt/send_cmd.py index 7a5181a..afdfc78 100755 --- a/send_cmd.py +++ b/src/pyvtt/send_cmd.py @@ -1,8 +1,7 @@ -#!/usr/bin/env python3 import socket import sys import argparse -from configuration import read_configurations +from src.pyvtt.configuration import read_configurations CONFIGURATION = read_configurations() @@ -25,14 +24,17 @@ def send_cmd(cmd: str, socket_path: str): """ try: with socket.socket(socket.AF_UNIX, socket.SOCK_STREAM) as client: + client.settimeout(3) client.connect(socket_path) client.sendall(cmd.encode()) except FileNotFoundError: - print(f"Error: The socket file '{socket_path}' does not exist.", file=sys.stderr) + print(f"Error: The socket file '{socket_path}' does not exist.", file=sys.stderr, flush=True) except ConnectionRefusedError: - print(f"Error: Connection to the server at '{socket_path}' was refused.", file=sys.stderr) + print(f"Error: Connection to the server at '{socket_path}' was refused.", file=sys.stderr, flush=True) + except socket.timeout: + print("Error: Socket operation timed out.", file=sys.stderr, flush=True) except OSError as e: - print(f"Socket error: {e}", file=sys.stderr) + print(f"Socket error: {e}", file=sys.stderr, flush=True) def main(): parser = argparse.ArgumentParser( @@ -47,7 +49,4 @@ def main(): ) args = parser.parse_args() - send_cmd(args.command, CONFIGURATION["socket_path"]) - -if __name__ == "__main__": - main() + send_cmd(args.command, CONFIGURATION["socket_path"]) \ No newline at end of file diff --git a/voice_to_text_tray.py b/src/pyvtt/voice_to_text_tray.py similarity index 74% rename from voice_to_text_tray.py rename to src/pyvtt/voice_to_text_tray.py index c127e2f..7cf17f8 100755 --- a/voice_to_text_tray.py +++ b/src/pyvtt/voice_to_text_tray.py @@ -1,4 +1,3 @@ -#!/usr/bin/env python3 import sys import subprocess import os @@ -9,8 +8,8 @@ import requests from PyQt5.QtWidgets import QApplication, QSystemTrayIcon, QMenu, QAction from PyQt5.QtGui import QIcon from PyQt5.QtCore import QThread, pyqtSignal -from configuration import read_configurations -from notify import notify +from src.pyvtt.configuration import read_configurations +from pyvtt.notify import notify, play_sound CONFIGURATION = read_configurations() CURRENT_PRESET = CONFIGURATION["presets"][0] # Default to first preset @@ -51,7 +50,7 @@ class WhisperWorker(QThread): try: with open(CONFIGURATION["output_file"], "r") as f: - raw_result = f.read().strip().replace("\n", " ") + raw_result = "\n".join(line.strip() for line in f.readlines()) except Exception as e: print(f"Datei Fehler: {e}") notify("Fehler", "Ein Fehler beim Lesen der Whisper-Ausgabe ist aufgetreten!") @@ -60,24 +59,40 @@ class WhisperWorker(QThread): print("Whisper Transkript erhalten.") # --- An Ollama schicken --- - payload = { - "model": CURRENT_PRESET["ollama_model"], - "prompt": CURRENT_PRESET["ollama_prompt"] + raw_result, - "stream": False - } - ollama_endpoint = f"{CONFIGURATION['ollama_url']}:{CONFIGURATION['ollama_port']}/api/generate" - response = requests.post(ollama_endpoint, json=payload) + if CURRENT_PRESET["ollama"] != "disable": + if isinstance(CURRENT_PRESET["ollama_prompt"], list): + prompt = "\n".join(CURRENT_PRESET["ollama_prompt"]) + else: + prompt = CURRENT_PRESET["ollama_prompt"] + + payload = { + "model": CURRENT_PRESET["ollama_model"], + "messages": [ + {"role": "system", "content": prompt}, + {"role": "user", "content": raw_result} + ], + "options": { + "num_ctx": CURRENT_PRESET["ollama_context"] + }, + "stream": False + } + ollama_endpoint = f"{CONFIGURATION['ollama_url']}:{CONFIGURATION['ollama_port']}/api/chat" + response = requests.post(ollama_endpoint, json=payload) - try: - response.raise_for_status() - except requests.exceptions.HTTPError as e: - print(f"HTTP Fehler: {e}") - notify("Fehler", "Ein Fehler bei der Kommunikation mit 'Ollama' ist aufgetreten!") - return + try: + response.raise_for_status() + except requests.exceptions.HTTPError as e: + print(f"HTTP Fehler: {e}") + notify("Fehler", "Ein Fehler bei der Kommunikation mit 'Ollama' ist aufgetreten!") + return - formatted_result = response.json().get("response", "").strip() - formatted_result = "\n".join(line.strip() for line in formatted_result.splitlines()) - print("Ollama Antwort erhalten.") + json_response = response.json() + formatted_result = json_response.get("message", {}).get("content", "").strip() + formatted_result = "\n".join(line.strip() for line in formatted_result.splitlines()) + print("Ollama Antwort erhalten.") + else: + formatted_result = raw_result + print("Kein Ollama Prompt angegeben, nur Whisper Ergebnis verwendet.") # Ergebnis ins Clipboard kopieren try: @@ -88,6 +103,7 @@ class WhisperWorker(QThread): return notify("Spracherkennung", "Transkription abgeschlossen!") + play_sound() self.finished.emit(formatted_result) except Exception as e: @@ -147,6 +163,7 @@ class TrayApp: preset_actions (list): A list of QAction objects representing the preset options. preset_group (QMenu): A submenu for managing presets. quit_action (QAction): An action to quit the application. + reload_action (QAction): An action to reload configurations. recording_process (subprocess.Popen or None): The process handling audio recording. socket_listener (SocketListener): A listener for socket communication. worker (WhisperWorker or None): A worker thread for processing audio with Whisper. @@ -159,6 +176,7 @@ class TrayApp: toggle_recording(): Toggles between starting and stopping the audio recording. start_whisper_worker(): Starts a WhisperWorker thread to process the recorded audio. show_result(text): Displays the processed text result from the WhisperWorker. + reload_configurations(): Reloads configurations from the settings file and updates the UI. cleanup(): Cleans up resources, such as removing the socket file, before the application exits. run(): Starts the application's event loop. """ @@ -182,6 +200,11 @@ class TrayApp: self.preset_actions.append(action) self.menu.addMenu(self.preset_group) + # Reload Configurations + self.reload_action = QAction("Einstellungen neu laden") + self.reload_action.triggered.connect(self.reload_configurations) + self.menu.addAction(self.reload_action) + # Quit self.quit_action = QAction("Beenden") self.quit_action.triggered.connect(self.app.quit) @@ -236,6 +259,24 @@ class TrayApp: def show_result(self, text): print(f"Fertig:\n{text}") + def reload_configurations(self): + global CONFIGURATION, CURRENT_PRESET + print("Lade Einstellungen neu...") + CONFIGURATION = read_configurations() + CURRENT_PRESET = CONFIGURATION["presets"][0] # Default to first preset + # Update preset menu + self.preset_group.clear() + self.preset_actions = [] + for i, preset in enumerate(CONFIGURATION["presets"]): + action = QAction(preset["name"], self.menu) + action.setCheckable(True) + if i == 0: + action.setChecked(True) + action.triggered.connect(lambda checked, index=i: self.set_preset(index)) + self.preset_group.addAction(action) + self.preset_actions.append(action) + print("Einstellungen erfolgreich neu geladen.") + def cleanup(self): if os.path.exists(CONFIGURATION["socket_path"]): os.remove(CONFIGURATION["socket_path"]) @@ -244,5 +285,5 @@ class TrayApp: def run(self): sys.exit(self.app.exec_()) -if __name__ == "__main__": +def main(): TrayApp().run() \ No newline at end of file