diff --git a/.github/workflows/build-pr.yaml b/.github/workflows/build-pr.yaml new file mode 100644 index 0000000..9edb47f --- /dev/null +++ b/.github/workflows/build-pr.yaml @@ -0,0 +1,80 @@ +name: Build Jetstream Turbo PR +on: + pull_request: + types: + - opened + - reopened + - labeled + - synchronize + +jobs: + build_jetstream_turbo_pr: + name: build_jetstream_turbo + outputs: + version_tag: ${{steps.version_tag.outputs.VERSION_TAG}} + if: contains(github.event.pull_request.labels.*.name, 'auto-build') + runs-on: ubuntu-latest + steps: + - name: checkout + uses: actions/checkout@v3 + + - name: version_tag + id: version_tag + run: | + short_sha=$(git rev-parse --short HEAD) + echo "_SHORT_SHA=$short_sha" >> $GITHUB_ENV + echo "VERSION_TAG=pr-${{github.event.pull_request.number}}-$short_sha-${{ github.run_number }}" >> $GITHUB_ENV + echo "VERSION_TAG=pr-${{github.event.pull_request.number}}-$short_sha-${{ github.run_number }}" >> $GITHUB_OUTPUT + + - name: configure_aws_credentials + uses: aws-actions/configure-aws-credentials@v4 + with: + aws-access-key-id: ${{ secrets.AWS_ACCESS_KEY }} + aws-secret-access-key: ${{ secrets.AWS_SECRET_KEY }} + role-to-assume: ${{ secrets.AWS_ASSUME_ROLE }} + role-external-id: grazebuilder + role-duration-seconds: 1200 + role-session-name: jestream-turbo-builder + role-skip-session-tagging: true + aws-region: ${{ secrets.ECR_REGION }} + + - name: Set up Docker CLI + uses: docker/setup-buildx-action@v3 + + - name: login_to_ecr + id: login-ecr + uses: aws-actions/amazon-ecr-login@v2 + with: + mask-password: "true" + + - name: build_and_push + uses: docker/build-push-action@v5 + with: + file: Dockerfile + context: . + cache-from: type=registry,ref=${{secrets.ECR_REPO}}:cache + cache-to: type=registry,mode=max,image-manifest=true,oci-mediatypes=true,ref=${{secrets.ECR_REPO}}:cache + push: true + tags: | + ${{ secrets.ECR_REPO }}:${{ env.VERSION_TAG }} + ${{ secrets.ECR_REPO }}:latest + builder: ${{ steps.setup_buildx.name }} + platforms: linux/amd64 + + - name: post_to_eng_alerts + uses: slackapi/slack-github-action@v2.1.1 + with: + webhook: ${{ secrets.SLACK_WEBHOOK_ENG_ALERTS }} + webhook-type: incoming-webhook + payload: | + text: "*`Jetstream Turbo Image`* ${{ env.VERSION_TAG }} Created" + blocks: + - type: "section" + text: + type: "mrkdwn" + text: "*`Jetstream Turbo` Image Created*" + - type: "divider" + - type: "section" + text: + type: "mrkdwn" + text: "Download:\n```${{secrets.ECR_REPO}}:${{ env.VERSION_TAG }}```" diff --git a/Dockerfile b/Dockerfile index 87301d1..1e2df70 100644 --- a/Dockerfile +++ b/Dockerfile @@ -27,7 +27,6 @@ RUN pdm install \ --fail-fast \ --lockfile ${LOCKFILE} - # Copy the rest of the project files (excluding `.venv`) COPY src ./src/ diff --git a/docker-compose.yml b/docker-compose.yml index c2d7f8d..52a6913 100644 --- a/docker-compose.yml +++ b/docker-compose.yml @@ -2,9 +2,9 @@ services: jetstream_turbo: build: . container_name: jetstream_turbo_service - restart: always - volumes: - - .:/app # Mount everything - - /app/.venv # But create an empty volume for `.venv` so it's not overwritten + #restart: always + # volumes: + # - .:/app # Mount everything + # - /app/.venv # But create an empty volume for `.venv` so it's not overwritten env_file: - .env # Load environment variables from .env diff --git a/pdm.lock b/pdm.lock index f1363ff..7a571eb 100644 --- a/pdm.lock +++ b/pdm.lock @@ -2,85 +2,74 @@ # It is not intended for manual editing. [metadata] -groups = ["default", "dev", "test"] +groups = ["default"] strategy = ["inherit_metadata"] lock_version = "4.5.0" -content_hash = "sha256:f572c4c0934e67660f526a9e353f10243331a006345d2765b140d564044905c9" +content_hash = "sha256:b81a58fc1ae93144b5133e6bc5bbb52fa6b7dd9725188612da3ac8b83e7d4fc8" [[metadata.targets]] requires_python = ">=3.11,<=3.12" -[[package]] -name = "aio-statsd" -version = "0.2.9" -requires_python = "<4.0,>=3.6" -summary = "an asyncio-based client for send metric to StatsD, Graphite.carbon, TelegrafStatsD and DogStatsD." -groups = ["default"] -files = [ - {file = "aio_statsd-0.2.9-py3-none-any.whl", hash = "sha256:d3358fe957ea1b219b55aecd90317b84672c22d2a54590ae4b94d2a41400fb02"}, - {file = "aio_statsd-0.2.9.tar.gz", hash = "sha256:349ea88dcda30a445e4174528b98074a3061ba057543a5ac0212a3aca6d63cc4"}, -] - [[package]] name = "aioboto3" -version = "14.1.0" -requires_python = "<4.0,>=3.8" +version = "15.2.0" +requires_python = ">=3.9" summary = "Async boto3 wrapper" groups = ["default"] dependencies = [ - "aiobotocore[boto3]==2.21.1", + "aiobotocore[boto3]==2.24.2", "aiofiles>=23.2.1", ] files = [ - {file = "aioboto3-14.1.0-py3-none-any.whl", hash = "sha256:f8547032bc4f90966b22869c1295d890c161549f4e8919f32853571ceb6fd0c6"}, - {file = "aioboto3-14.1.0.tar.gz", hash = "sha256:9d59b536ae8a951b9413ce151bf77df9c7cfe2cbaa2c4c240c066f384305c932"}, + {file = "aioboto3-15.2.0-py3-none-any.whl", hash = "sha256:3582f033543ee7671ae27b1df538f2095bcc91be4a3a78e7498b5ce6c654f26b"}, + {file = "aioboto3-15.2.0.tar.gz", hash = "sha256:6a151ee0aa0f4b9af6031e6446f28460991fcc50a4ac54a1650d145319d5e2e5"}, ] [[package]] name = "aiobotocore" -version = "2.21.1" -requires_python = ">=3.8" +version = "2.24.2" +requires_python = ">=3.9" summary = "Async client for aws services using botocore and aiohttp" groups = ["default"] dependencies = [ "aiohttp<4.0.0,>=3.9.2", "aioitertools<1.0.0,>=0.5.1", - "botocore<1.37.2,>=1.37.0", + "botocore<1.40.19,>=1.40.15", "jmespath<2.0.0,>=0.7.1", "multidict<7.0.0,>=6.0.0", "python-dateutil<3.0.0,>=2.1", "wrapt<2.0.0,>=1.10.10", ] files = [ - {file = "aiobotocore-2.21.1-py3-none-any.whl", hash = "sha256:bd7c49a6d6f8a3d9444b0a94417c8da13813b5c7eec1c4f0ec2db7e8ce8f23e7"}, - {file = "aiobotocore-2.21.1.tar.gz", hash = "sha256:010357f43004413e92a9d066bb0db1f241aeb29ffed306e9197061ffc94e6577"}, + {file = "aiobotocore-2.24.2-py3-none-any.whl", hash = "sha256:808c63b2bd344b91e2f2acb874831118a9f53342d248acd16a68455a226e283a"}, + {file = "aiobotocore-2.24.2.tar.gz", hash = "sha256:dfb21bdb2610e8de4d22f401e91a24d50f1330a302d03c62c485757becd439a9"}, ] [[package]] name = "aiobotocore" -version = "2.21.1" +version = "2.24.2" extras = ["boto3"] -requires_python = ">=3.8" +requires_python = ">=3.9" summary = "Async client for aws services using botocore and aiohttp" groups = ["default"] dependencies = [ - "aiobotocore==2.21.1", - "boto3<1.37.2,>=1.37.0", + "aiobotocore==2.24.2", + "boto3<1.40.19,>=1.40.15", ] files = [ - {file = "aiobotocore-2.21.1-py3-none-any.whl", hash = "sha256:bd7c49a6d6f8a3d9444b0a94417c8da13813b5c7eec1c4f0ec2db7e8ce8f23e7"}, - {file = "aiobotocore-2.21.1.tar.gz", hash = "sha256:010357f43004413e92a9d066bb0db1f241aeb29ffed306e9197061ffc94e6577"}, + {file = "aiobotocore-2.24.2-py3-none-any.whl", hash = "sha256:808c63b2bd344b91e2f2acb874831118a9f53342d248acd16a68455a226e283a"}, + {file = "aiobotocore-2.24.2.tar.gz", hash = "sha256:dfb21bdb2610e8de4d22f401e91a24d50f1330a302d03c62c485757becd439a9"}, ] [[package]] name = "aiofiles" -version = "24.1.0" -requires_python = ">=3.8" +version = "25.1.0" +requires_python = ">=3.9" summary = "File support for asyncio." groups = ["default"] files = [ - {file = "aiofiles-24.1.0-py3-none-any.whl", hash = "sha256:b4ec55f4195e3eb5d7abd1bf7e061763e864dd4954231fb8539a0ef8bb8260e5"}, - {file = "aiofiles-24.1.0.tar.gz", hash = "sha256:22a075c9e5a3810f0c2e48f3008c94d68c65d763b9b03857924c99e57355166c"}, + {file = "aiofiles-25.1.0-py3-none-any.whl", hash = "sha256:abe311e527c862958650f9438e859c1fa7568a141b22abcd015e120e86a85695"}, + {file = "aiofiles-25.1.0.tar.gz", hash = "sha256:a8d728f0a29de45dc521f18f07297428d56992a742f0cd2701ba86e44d23d5b2"}, ] [[package]] @@ -96,13 +85,13 @@ files = [ [[package]] name = "aiohttp" -version = "3.11.18" +version = "3.13.0" requires_python = ">=3.9" summary = "Async http client/server framework (asyncio)" groups = ["default"] dependencies = [ - "aiohappyeyeballs>=2.3.0", - "aiosignal>=1.1.2", + "aiohappyeyeballs>=2.5.0", + "aiosignal>=1.4.0", "async-timeout<6.0,>=4.0; python_version < \"3.11\"", "attrs>=17.3.0", "frozenlist>=1.1.1", @@ -111,54 +100,41 @@ dependencies = [ "yarl<2.0,>=1.17.0", ] files = [ - {file = "aiohttp-3.11.18-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:427fdc56ccb6901ff8088544bde47084845ea81591deb16f957897f0f0ba1be9"}, - {file = "aiohttp-3.11.18-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:2c828b6d23b984255b85b9b04a5b963a74278b7356a7de84fda5e3b76866597b"}, - {file = "aiohttp-3.11.18-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:5c2eaa145bb36b33af1ff2860820ba0589e165be4ab63a49aebfd0981c173b66"}, - {file = "aiohttp-3.11.18-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d518ce32179f7e2096bf4e3e8438cf445f05fedd597f252de9f54c728574756"}, - {file = "aiohttp-3.11.18-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:0700055a6e05c2f4711011a44364020d7a10fbbcd02fbf3e30e8f7e7fddc8717"}, - {file = "aiohttp-3.11.18-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:8bd1cde83e4684324e6ee19adfc25fd649d04078179890be7b29f76b501de8e4"}, - {file = "aiohttp-3.11.18-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:73b8870fe1c9a201b8c0d12c94fe781b918664766728783241a79e0468427e4f"}, - {file = "aiohttp-3.11.18-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:25557982dd36b9e32c0a3357f30804e80790ec2c4d20ac6bcc598533e04c6361"}, - {file = "aiohttp-3.11.18-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:7e889c9df381a2433802991288a61e5a19ceb4f61bd14f5c9fa165655dcb1fd1"}, - {file = "aiohttp-3.11.18-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:9ea345fda05bae217b6cce2acf3682ce3b13d0d16dd47d0de7080e5e21362421"}, - {file = "aiohttp-3.11.18-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9f26545b9940c4b46f0a9388fd04ee3ad7064c4017b5a334dd450f616396590e"}, - {file = "aiohttp-3.11.18-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:3a621d85e85dccabd700294494d7179ed1590b6d07a35709bb9bd608c7f5dd1d"}, - {file = "aiohttp-3.11.18-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:9c23fd8d08eb9c2af3faeedc8c56e134acdaf36e2117ee059d7defa655130e5f"}, - {file = "aiohttp-3.11.18-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:d9e6b0e519067caa4fd7fb72e3e8002d16a68e84e62e7291092a5433763dc0dd"}, - {file = "aiohttp-3.11.18-cp311-cp311-win32.whl", hash = "sha256:122f3e739f6607e5e4c6a2f8562a6f476192a682a52bda8b4c6d4254e1138f4d"}, - {file = "aiohttp-3.11.18-cp311-cp311-win_amd64.whl", hash = "sha256:e6f3c0a3a1e73e88af384b2e8a0b9f4fb73245afd47589df2afcab6b638fa0e6"}, - {file = "aiohttp-3.11.18-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:63d71eceb9cad35d47d71f78edac41fcd01ff10cacaa64e473d1aec13fa02df2"}, - {file = "aiohttp-3.11.18-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:d1929da615840969929e8878d7951b31afe0bac883d84418f92e5755d7b49508"}, - {file = "aiohttp-3.11.18-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7d0aebeb2392f19b184e3fdd9e651b0e39cd0f195cdb93328bd124a1d455cd0e"}, - {file = "aiohttp-3.11.18-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3849ead845e8444f7331c284132ab314b4dac43bfae1e3cf350906d4fff4620f"}, - {file = "aiohttp-3.11.18-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5e8452ad6b2863709f8b3d615955aa0807bc093c34b8e25b3b52097fe421cb7f"}, - {file = "aiohttp-3.11.18-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:3b8d2b42073611c860a37f718b3d61ae8b4c2b124b2e776e2c10619d920350ec"}, - {file = "aiohttp-3.11.18-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:40fbf91f6a0ac317c0a07eb328a1384941872f6761f2e6f7208b63c4cc0a7ff6"}, - {file = "aiohttp-3.11.18-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:44ff5625413fec55216da5eaa011cf6b0a2ed67a565914a212a51aa3755b0009"}, - {file = "aiohttp-3.11.18-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:7f33a92a2fde08e8c6b0c61815521324fc1612f397abf96eed86b8e31618fdb4"}, - {file = "aiohttp-3.11.18-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:11d5391946605f445ddafda5eab11caf310f90cdda1fd99865564e3164f5cff9"}, - {file = "aiohttp-3.11.18-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:3cc314245deb311364884e44242e00c18b5896e4fe6d5f942e7ad7e4cb640adb"}, - {file = "aiohttp-3.11.18-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:0f421843b0f70740772228b9e8093289924359d306530bcd3926f39acbe1adda"}, - {file = "aiohttp-3.11.18-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:e220e7562467dc8d589e31c1acd13438d82c03d7f385c9cd41a3f6d1d15807c1"}, - {file = "aiohttp-3.11.18-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ab2ef72f8605046115bc9aa8e9d14fd49086d405855f40b79ed9e5c1f9f4faea"}, - {file = "aiohttp-3.11.18-cp312-cp312-win32.whl", hash = "sha256:12a62691eb5aac58d65200c7ae94d73e8a65c331c3a86a2e9670927e94339ee8"}, - {file = "aiohttp-3.11.18-cp312-cp312-win_amd64.whl", hash = "sha256:364329f319c499128fd5cd2d1c31c44f234c58f9b96cc57f743d16ec4f3238c8"}, - {file = "aiohttp-3.11.18.tar.gz", hash = "sha256:ae856e1138612b7e412db63b7708735cff4d38d0399f6a5435d3dac2669f558a"}, -] - -[[package]] -name = "aiohttp-jinja2" -version = "1.6" -requires_python = ">=3.8" -summary = "jinja2 template renderer for aiohttp.web (http server for asyncio)" -groups = ["default"] -dependencies = [ - "aiohttp>=3.9.0", - "jinja2>=3.0.0", -] -files = [ - {file = "aiohttp-jinja2-1.6.tar.gz", hash = "sha256:a3a7ff5264e5bca52e8ae547bbfd0761b72495230d438d05b6c0915be619b0e2"}, - {file = "aiohttp_jinja2-1.6-py3-none-any.whl", hash = "sha256:0df405ee6ad1b58e5a068a105407dc7dcc1704544c559f1938babde954f945c7"}, + {file = "aiohttp-3.13.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:99eb94e97a42367fef5fc11e28cb2362809d3e70837f6e60557816c7106e2e20"}, + {file = "aiohttp-3.13.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4696665b2713021c6eba3e2b882a86013763b442577fe5d2056a42111e732eca"}, + {file = "aiohttp-3.13.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:3e6a38366f7f0d0f6ed7a1198055150c52fda552b107dad4785c0852ad7685d1"}, + {file = "aiohttp-3.13.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:aab715b1a0c37f7f11f9f1f579c6fbaa51ef569e47e3c0a4644fba46077a9409"}, + {file = "aiohttp-3.13.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7972c82bed87d7bd8e374b60a6b6e816d75ba4f7c2627c2d14eed216e62738e1"}, + {file = "aiohttp-3.13.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ca8313cb852af788c78d5afdea24c40172cbfff8b35e58b407467732fde20390"}, + {file = "aiohttp-3.13.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:6c333a2385d2a6298265f4b3e960590f787311b87f6b5e6e21bb8375914ef504"}, + {file = "aiohttp-3.13.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:cc6d5fc5edbfb8041d9607f6a417997fa4d02de78284d386bea7ab767b5ea4f3"}, + {file = "aiohttp-3.13.0-cp311-cp311-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:7ddedba3d0043349edc79df3dc2da49c72b06d59a45a42c1c8d987e6b8d175b8"}, + {file = "aiohttp-3.13.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:23ca762140159417a6bbc959ca1927f6949711851e56f2181ddfe8d63512b5ad"}, + {file = "aiohttp-3.13.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:bfe824d6707a5dc3c5676685f624bc0c63c40d79dc0239a7fd6c034b98c25ebe"}, + {file = "aiohttp-3.13.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:3c11fa5dd2ef773a8a5a6daa40243d83b450915992eab021789498dc87acc114"}, + {file = "aiohttp-3.13.0-cp311-cp311-musllinux_1_2_riscv64.whl", hash = "sha256:00fdfe370cffede3163ba9d3f190b32c0cfc8c774f6f67395683d7b0e48cdb8a"}, + {file = "aiohttp-3.13.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:6475e42ef92717a678bfbf50885a682bb360a6f9c8819fb1a388d98198fdcb80"}, + {file = "aiohttp-3.13.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:77da5305a410910218b99f2a963092f4277d8a9c1f429c1ff1b026d1826bd0b6"}, + {file = "aiohttp-3.13.0-cp311-cp311-win32.whl", hash = "sha256:2f9d9ea547618d907f2ee6670c9a951f059c5994e4b6de8dcf7d9747b420c820"}, + {file = "aiohttp-3.13.0-cp311-cp311-win_amd64.whl", hash = "sha256:0f19f7798996d4458c669bd770504f710014926e9970f4729cf55853ae200469"}, + {file = "aiohttp-3.13.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1c272a9a18a5ecc48a7101882230046b83023bb2a662050ecb9bfcb28d9ab53a"}, + {file = "aiohttp-3.13.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:97891a23d7fd4e1afe9c2f4473e04595e4acb18e4733b910b6577b74e7e21985"}, + {file = "aiohttp-3.13.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:475bd56492ce5f4cffe32b5533c6533ee0c406d1d0e6924879f83adcf51da0ae"}, + {file = "aiohttp-3.13.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:c32ada0abb4bc94c30be2b681c42f058ab104d048da6f0148280a51ce98add8c"}, + {file = "aiohttp-3.13.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:4af1f8877ca46ecdd0bc0d4a6b66d4b2bddc84a79e2e8366bc0d5308e76bceb8"}, + {file = "aiohttp-3.13.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:e04ab827ec4f775817736b20cdc8350f40327f9b598dec4e18c9ffdcbea88a93"}, + {file = "aiohttp-3.13.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:a6d9487b9471ec36b0faedf52228cd732e89be0a2bbd649af890b5e2ce422353"}, + {file = "aiohttp-3.13.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:2e66c57416352f36bf98f6641ddadd47c93740a22af7150d3e9a1ef6e983f9a8"}, + {file = "aiohttp-3.13.0-cp312-cp312-manylinux_2_31_riscv64.manylinux_2_39_riscv64.whl", hash = "sha256:469167d5372f5bb3aedff4fc53035d593884fff2617a75317740e885acd48b04"}, + {file = "aiohttp-3.13.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a9f3546b503975a69b547c9fd1582cad10ede1ce6f3e313a2f547c73a3d7814f"}, + {file = "aiohttp-3.13.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:6b4174fcec98601f0cfdf308ee29a6ae53c55f14359e848dab4e94009112ee7d"}, + {file = "aiohttp-3.13.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:a533873a7a4ec2270fb362ee5a0d3b98752e4e1dc9042b257cd54545a96bd8ed"}, + {file = "aiohttp-3.13.0-cp312-cp312-musllinux_1_2_riscv64.whl", hash = "sha256:ce887c5e54411d607ee0959cac15bb31d506d86a9bcaddf0b7e9d63325a7a802"}, + {file = "aiohttp-3.13.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:d871f6a30d43e32fc9252dc7b9febe1a042b3ff3908aa83868d7cf7c9579a59b"}, + {file = "aiohttp-3.13.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:222c828243b4789d79a706a876910f656fad4381661691220ba57b2ab4547865"}, + {file = "aiohttp-3.13.0-cp312-cp312-win32.whl", hash = "sha256:682d2e434ff2f1108314ff7f056ce44e457f12dbed0249b24e106e385cf154b9"}, + {file = "aiohttp-3.13.0-cp312-cp312-win_amd64.whl", hash = "sha256:0a2be20eb23888df130214b91c262a90e2de1553d6fb7de9e9010cec994c0ff2"}, + {file = "aiohttp-3.13.0.tar.gz", hash = "sha256:378dbc57dd8cf341ce243f13fa1fa5394d68e2e02c15cd5f28eae35a70ec7f67"}, ] [[package]] @@ -188,16 +164,17 @@ files = [ [[package]] name = "aiosignal" -version = "1.3.2" +version = "1.4.0" requires_python = ">=3.9" summary = "aiosignal: a list of registered asynchronous callbacks" groups = ["default"] dependencies = [ "frozenlist>=1.1.0", + "typing-extensions>=4.2; python_version < \"3.13\"", ] files = [ - {file = "aiosignal-1.3.2-py2.py3-none-any.whl", hash = "sha256:45cde58e409a301715980c2b01d0c28bdde3770d8290b5eb2173759d9acb31a5"}, - {file = "aiosignal-1.3.2.tar.gz", hash = "sha256:a8c255c66fafb1e499c9351d0bf32ff2d8a0321595ebac3b93713656d2436f54"}, + {file = "aiosignal-1.4.0-py3-none-any.whl", hash = "sha256:053243f8b92b990551949e63930a839ff0cf0b0ebbe0597b0f3fb19e1a0fe82e"}, + {file = "aiosignal-1.4.0.tar.gz", hash = "sha256:f47eecd9468083c2029cc99945502cb7708b082c232f9aca65da147157b251c7"}, ] [[package]] @@ -216,9 +193,9 @@ files = [ [[package]] name = "anyio" -version = "4.9.0" +version = "4.11.0" requires_python = ">=3.9" -summary = "High level compatibility layer for multiple asynchronous event loop implementations" +summary = "High-level concurrency and networking framework on top of asyncio or Trio" groups = ["default"] dependencies = [ "exceptiongroup>=1.0.2; python_version < \"3.11\"", @@ -227,8 +204,8 @@ dependencies = [ "typing-extensions>=4.5; python_version < \"3.13\"", ] files = [ - {file = "anyio-4.9.0-py3-none-any.whl", hash = "sha256:9f76d541cad6e36af7beb62e978876f3b41e3e04f2c1fbf0884604c0a9c4d93c"}, - {file = "anyio-4.9.0.tar.gz", hash = "sha256:673c0c244e15788651a4ff38710fea9675823028a6f08a5eda409e0c9840a028"}, + {file = "anyio-4.11.0-py3-none-any.whl", hash = "sha256:0287e96f4d26d4149305414d4e3bc32f0dcd0862365a4bddea19d7a1ec38c4fc"}, + {file = "anyio-4.11.0.tar.gz", hash = "sha256:82a8d0b81e318cc5ce71a5f1f8b5c4e63619620b63141ef8c995fa0db95a57c4"}, ] [[package]] @@ -245,7 +222,7 @@ files = [ [[package]] name = "atproto" -version = "0.0.61" +version = "0.0.62" requires_python = "<3.14,>=3.8" summary = "The AT Protocol SDK" groups = ["default"] @@ -260,69 +237,41 @@ dependencies = [ "websockets<14,>=12", ] files = [ - {file = "atproto-0.0.61-py3-none-any.whl", hash = "sha256:658da5832aaeea4a12a9a74235f9c90c11453e77d596fdccb1f8b39d56245b88"}, - {file = "atproto-0.0.61.tar.gz", hash = "sha256:98e022daf538d14f134ce7c91d42c4c973f3493ac56e43a84daa4c881f102beb"}, + {file = "atproto-0.0.62-py3-none-any.whl", hash = "sha256:d655d37bbf00659bcb6f166e00806096e083047bc91a8b90a260c5f2e6cab250"}, + {file = "atproto-0.0.62.tar.gz", hash = "sha256:1aaf4555ca1b318b003ad3e9e46d141e9deb5a954360a743a5aa873cd8f17b93"}, ] [[package]] name = "attrs" -version = "25.3.0" -requires_python = ">=3.8" +version = "25.4.0" +requires_python = ">=3.9" summary = "Classes Without Boilerplate" groups = ["default"] files = [ - {file = "attrs-25.3.0-py3-none-any.whl", hash = "sha256:427318ce031701fea540783410126f03899a97ffc6f61596ad581ac2e40e3bc3"}, - {file = "attrs-25.3.0.tar.gz", hash = "sha256:75d7cefc7fb576747b2c81b4442d4d4a1ce0900973527c011d1030fd3bf4af1b"}, -] - -[[package]] -name = "black" -version = "25.1.0" -requires_python = ">=3.9" -summary = "The uncompromising code formatter." -groups = ["dev"] -dependencies = [ - "click>=8.0.0", - "mypy-extensions>=0.4.3", - "packaging>=22.0", - "pathspec>=0.9.0", - "platformdirs>=2", - "tomli>=1.1.0; python_version < \"3.11\"", - "typing-extensions>=4.0.1; python_version < \"3.11\"", -] -files = [ - {file = "black-25.1.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:a39337598244de4bae26475f77dda852ea00a93bd4c728e09eacd827ec929df0"}, - {file = "black-25.1.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:96c1c7cd856bba8e20094e36e0f948718dc688dba4a9d78c3adde52b9e6c2299"}, - {file = "black-25.1.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:bce2e264d59c91e52d8000d507eb20a9aca4a778731a08cfff7e5ac4a4bb7096"}, - {file = "black-25.1.0-cp311-cp311-win_amd64.whl", hash = "sha256:172b1dbff09f86ce6f4eb8edf9dede08b1fce58ba194c87d7a4f1a5aa2f5b3c2"}, - {file = "black-25.1.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:4b60580e829091e6f9238c848ea6750efed72140b91b048770b64e74fe04908b"}, - {file = "black-25.1.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:1e2978f6df243b155ef5fa7e558a43037c3079093ed5d10fd84c43900f2d8ecc"}, - {file = "black-25.1.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3b48735872ec535027d979e8dcb20bf4f70b5ac75a8ea99f127c106a7d7aba9f"}, - {file = "black-25.1.0-cp312-cp312-win_amd64.whl", hash = "sha256:ea0213189960bda9cf99be5b8c8ce66bb054af5e9e861249cd23471bd7b0b3ba"}, - {file = "black-25.1.0-py3-none-any.whl", hash = "sha256:95e8176dae143ba9097f351d174fdaf0ccd29efb414b362ae3fd72bf0f710717"}, - {file = "black-25.1.0.tar.gz", hash = "sha256:33496d5cd1222ad73391352b4ae8da15253c5de89b93a80b3e2c8d9a19ec2666"}, + {file = "attrs-25.4.0-py3-none-any.whl", hash = "sha256:adcf7e2a1fb3b36ac48d97835bb6d8ade15b8dcce26aba8bf1d14847b57a3373"}, + {file = "attrs-25.4.0.tar.gz", hash = "sha256:16d5969b87f0859ef33a48b35d55ac1be6e42ae49d5e853b597db70c35c57e11"}, ] [[package]] name = "boto3" -version = "1.37.1" -requires_python = ">=3.8" +version = "1.40.18" +requires_python = ">=3.9" summary = "The AWS SDK for Python" groups = ["default"] dependencies = [ - "botocore<1.38.0,>=1.37.1", + "botocore<1.41.0,>=1.40.18", "jmespath<2.0.0,>=0.7.1", - "s3transfer<0.12.0,>=0.11.0", + "s3transfer<0.14.0,>=0.13.0", ] files = [ - {file = "boto3-1.37.1-py3-none-any.whl", hash = "sha256:4320441f904435a1b85e6ecb81793192e522c737cc9ed6566014e29f0a11cb22"}, - {file = "boto3-1.37.1.tar.gz", hash = "sha256:96d18f7feb0c1fcb95f8837b74b6c8880e1b4e35ce5f8a8f8cb243a090c278ed"}, + {file = "boto3-1.40.18-py3-none-any.whl", hash = "sha256:daa776ba1251a7458c9d6c7627873d0c2460c8e8272d35759065580e9193700a"}, + {file = "boto3-1.40.18.tar.gz", hash = "sha256:64301d39adecc154e3e595eaf0d4f28998ef0a5551f1d033aeac51a9e1a688e5"}, ] [[package]] name = "botocore" -version = "1.37.1" -requires_python = ">=3.8" +version = "1.40.18" +requires_python = ">=3.9" summary = "Low-level, data-driven core of boto 3." groups = ["default"] dependencies = [ @@ -332,71 +281,86 @@ dependencies = [ "urllib3<1.27,>=1.25.4; python_version < \"3.10\"", ] files = [ - {file = "botocore-1.37.1-py3-none-any.whl", hash = "sha256:c1db1bfc5d8c6b3b6d1ca6794f605294b4264e82a7e727b88e0fef9c2b9fbb9c"}, - {file = "botocore-1.37.1.tar.gz", hash = "sha256:b194db8fb2a0ffba53568c364ae26166e7eec0445496b2ac86a6e142f3dd982f"}, + {file = "botocore-1.40.18-py3-none-any.whl", hash = "sha256:57025c46ca00cf8cec25de07a759521bfbfb3036a0f69b272654a354615dc45f"}, + {file = "botocore-1.40.18.tar.gz", hash = "sha256:afd69bdadd8c55cc89d69de0799829e555193a352d87867f746e19020271cc0f"}, +] + +[[package]] +name = "botocore-stubs" +version = "1.40.50" +requires_python = ">=3.9" +summary = "Type annotations and code completion for botocore" +groups = ["default"] +dependencies = [ + "types-awscrt", +] +files = [ + {file = "botocore_stubs-1.40.50-py3-none-any.whl", hash = "sha256:7cb8d636e061e600929cd03339c3bbc162c21435b4bfeb6413cf7b0b612e7de0"}, + {file = "botocore_stubs-1.40.50.tar.gz", hash = "sha256:d772b2d3aea6b4e464963fe45b2d504eee7bc3842f047cebbae5492b3993e0fd"}, ] [[package]] name = "certifi" -version = "2025.1.31" -requires_python = ">=3.6" +version = "2025.10.5" +requires_python = ">=3.7" summary = "Python package for providing Mozilla's CA Bundle." groups = ["default"] files = [ - {file = "certifi-2025.1.31-py3-none-any.whl", hash = "sha256:ca78db4565a652026a4db2bcdf68f2fb589ea80d0be70e03929ed730746b84fe"}, - {file = "certifi-2025.1.31.tar.gz", hash = "sha256:3d5da6925056f6f18f119200434a4780a94263f10d1c21d032a6f6b2baa20651"}, + {file = "certifi-2025.10.5-py3-none-any.whl", hash = "sha256:0f212c2744a9bb6de0c56639a6f68afe01ecd92d91f14ae897c4fe7bbeeef0de"}, + {file = "certifi-2025.10.5.tar.gz", hash = "sha256:47c09d31ccf2acf0be3f701ea53595ee7e0b8fa08801c6624be771df09ae7b43"}, ] [[package]] name = "cffi" -version = "1.17.1" -requires_python = ">=3.8" +version = "2.0.0" +requires_python = ">=3.9" summary = "Foreign Function Interface for Python calling C code." groups = ["default"] marker = "platform_python_implementation != \"PyPy\"" dependencies = [ - "pycparser", -] -files = [ - {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.tar.gz", hash = "sha256:1c39c6016c32bc48dd54561950ebd6836e1670f2ae46128f67cf49e789c52824"}, + "pycparser; implementation_name != \"PyPy\"", +] +files = [ + {file = "cffi-2.0.0-cp311-cp311-macosx_10_13_x86_64.whl", hash = "sha256:b4c854ef3adc177950a8dfc81a86f5115d2abd545751a304c5bcf2c2c7283cfe"}, + {file = "cffi-2.0.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2de9a304e27f7596cd03d16f1b7c72219bd944e99cc52b84d0145aefb07cbd3c"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:baf5215e0ab74c16e2dd324e8ec067ef59e41125d3eade2b863d294fd5035c92"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:730cacb21e1bdff3ce90babf007d0a0917cc3e6492f336c2f0134101e0944f93"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:6824f87845e3396029f3820c206e459ccc91760e8fa24422f8b0c3d1731cbec5"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:9de40a7b0323d889cf8d23d1ef214f565ab154443c42737dfe52ff82cf857664"}, + {file = "cffi-2.0.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:8941aaadaf67246224cee8c3803777eed332a19d909b47e29c9842ef1e79ac26"}, + {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:a05d0c237b3349096d3981b727493e22147f934b20f6f125a3eba8f994bec4a9"}, + {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:94698a9c5f91f9d138526b48fe26a199609544591f859c870d477351dc7b2414"}, + {file = "cffi-2.0.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:5fed36fccc0612a53f1d4d9a816b50a36702c28a2aa880cb8a122b3466638743"}, + {file = "cffi-2.0.0-cp311-cp311-win32.whl", hash = "sha256:c649e3a33450ec82378822b3dad03cc228b8f5963c0c12fc3b1e0ab940f768a5"}, + {file = "cffi-2.0.0-cp311-cp311-win_amd64.whl", hash = "sha256:66f011380d0e49ed280c789fbd08ff0d40968ee7b665575489afa95c98196ab5"}, + {file = "cffi-2.0.0-cp311-cp311-win_arm64.whl", hash = "sha256:c6638687455baf640e37344fe26d37c404db8b80d037c3d29f58fe8d1c3b194d"}, + {file = "cffi-2.0.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:6d02d6655b0e54f54c4ef0b94eb6be0607b70853c45ce98bd278dc7de718be5d"}, + {file = "cffi-2.0.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8eca2a813c1cb7ad4fb74d368c2ffbbb4789d377ee5bb8df98373c2cc0dee76c"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux1_i686.manylinux2014_i686.manylinux_2_17_i686.manylinux_2_5_i686.whl", hash = "sha256:21d1152871b019407d8ac3985f6775c079416c282e431a4da6afe7aefd2bccbe"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:b21e08af67b8a103c71a250401c78d5e0893beff75e28c53c98f4de42f774062"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.whl", hash = "sha256:1e3a615586f05fc4065a8b22b8152f0c1b00cdbc60596d187c2a74f9e3036e4e"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.whl", hash = "sha256:81afed14892743bbe14dacb9e36d9e0e504cd204e0b165062c488942b9718037"}, + {file = "cffi-2.0.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3e17ed538242334bf70832644a32a7aae3d83b57567f9fd60a26257e992b79ba"}, + {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:3925dd22fa2b7699ed2617149842d2e6adde22b262fcbfada50e3d195e4b3a94"}, + {file = "cffi-2.0.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:2c8f814d84194c9ea681642fd164267891702542f028a15fc97d4674b6206187"}, + {file = "cffi-2.0.0-cp312-cp312-win32.whl", hash = "sha256:da902562c3e9c550df360bfa53c035b2f241fed6d9aef119048073680ace4a18"}, + {file = "cffi-2.0.0-cp312-cp312-win_amd64.whl", hash = "sha256:da68248800ad6320861f129cd9c1bf96ca849a2771a59e0344e88681905916f5"}, + {file = "cffi-2.0.0-cp312-cp312-win_arm64.whl", hash = "sha256:4671d9dd5ec934cb9a73e7ee9676f9362aba54f7f34910956b84d727b0d73fb6"}, + {file = "cffi-2.0.0.tar.gz", hash = "sha256:44d1b5909021139fe36001ae048dbdde8214afa20200eda0f64c068cac5d5529"}, ] [[package]] name = "click" -version = "8.1.8" -requires_python = ">=3.7" +version = "8.3.0" +requires_python = ">=3.10" summary = "Composable command line interface toolkit" -groups = ["default", "dev"] +groups = ["default"] dependencies = [ "colorama; platform_system == \"Windows\"", - "importlib-metadata; python_version < \"3.8\"", ] files = [ - {file = "click-8.1.8-py3-none-any.whl", hash = "sha256:63c132bbbed01578a06712a2d1f497bb62d9c1c0d329b7903a866228027263b2"}, - {file = "click-8.1.8.tar.gz", hash = "sha256:ed53c9d8990d83c2a27deae68e4ee337473f6330c040a31d4225c9574d16096a"}, + {file = "click-8.3.0-py3-none-any.whl", hash = "sha256:9b9f285302c6e3064f4330c05f05b81945b2a39544279343e6e7c5f27a9baddc"}, + {file = "click-8.3.0.tar.gz", hash = "sha256:e7b8232224eba16f4ebe410c25ced9f7875cb5f3263ffc93cc3e8da705e229c4"}, ] [[package]] @@ -404,185 +368,134 @@ name = "colorama" version = "0.4.6" requires_python = "!=3.0.*,!=3.1.*,!=3.2.*,!=3.3.*,!=3.4.*,!=3.5.*,!=3.6.*,>=2.7" summary = "Cross-platform colored terminal text." -groups = ["default", "dev"] -marker = "sys_platform == \"win32\" or platform_system == \"Windows\"" +groups = ["default"] +marker = "platform_system == \"Windows\"" files = [ {file = "colorama-0.4.6-py2.py3-none-any.whl", hash = "sha256:4f1d9991f5acc0ca119f9d443620b77f9d6b33703e51011c16baf57afb285fc6"}, {file = "colorama-0.4.6.tar.gz", hash = "sha256:08695f5cb7ed6e0531a20572697297273c47b8cae5a63ffc6d6ed5c201be6e44"}, ] -[[package]] -name = "coverage" -version = "7.8.0" -requires_python = ">=3.9" -summary = "Code coverage measurement for Python" -groups = ["test"] -files = [ - {file = "coverage-7.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:e7ac22a0bb2c7c49f441f7a6d46c9c80d96e56f5a8bc6972529ed43c8b694e27"}, - {file = "coverage-7.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bf13d564d310c156d1c8e53877baf2993fb3073b2fc9f69790ca6a732eb4bfea"}, - {file = "coverage-7.8.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:a5761c70c017c1b0d21b0815a920ffb94a670c8d5d409d9b38857874c21f70d7"}, - {file = "coverage-7.8.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:e5ff52d790c7e1628241ffbcaeb33e07d14b007b6eb00a19320c7b8a7024c040"}, - {file = "coverage-7.8.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d39fc4817fd67b3915256af5dda75fd4ee10621a3d484524487e33416c6f3543"}, - {file = "coverage-7.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b44674870709017e4b4036e3d0d6c17f06a0e6d4436422e0ad29b882c40697d2"}, - {file = "coverage-7.8.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:8f99eb72bf27cbb167b636eb1726f590c00e1ad375002230607a844d9e9a2318"}, - {file = "coverage-7.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b571bf5341ba8c6bc02e0baeaf3b061ab993bf372d982ae509807e7f112554e9"}, - {file = "coverage-7.8.0-cp311-cp311-win32.whl", hash = "sha256:e75a2ad7b647fd8046d58c3132d7eaf31b12d8a53c0e4b21fa9c4d23d6ee6d3c"}, - {file = "coverage-7.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:3043ba1c88b2139126fc72cb48574b90e2e0546d4c78b5299317f61b7f718b78"}, - {file = "coverage-7.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:bbb5cc845a0292e0c520656d19d7ce40e18d0e19b22cb3e0409135a575bf79fc"}, - {file = "coverage-7.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:4dfd9a93db9e78666d178d4f08a5408aa3f2474ad4d0e0378ed5f2ef71640cb6"}, - {file = "coverage-7.8.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f017a61399f13aa6d1039f75cd467be388d157cd81f1a119b9d9a68ba6f2830d"}, - {file = "coverage-7.8.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:0915742f4c82208ebf47a2b154a5334155ed9ef9fe6190674b8a46c2fb89cb05"}, - {file = "coverage-7.8.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:8a40fcf208e021eb14b0fac6bdb045c0e0cab53105f93ba0d03fd934c956143a"}, - {file = "coverage-7.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:a1f406a8e0995d654b2ad87c62caf6befa767885301f3b8f6f73e6f3c31ec3a6"}, - {file = "coverage-7.8.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:77af0f6447a582fdc7de5e06fa3757a3ef87769fbb0fdbdeba78c23049140a47"}, - {file = "coverage-7.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:f2d32f95922927186c6dbc8bc60df0d186b6edb828d299ab10898ef3f40052fe"}, - {file = "coverage-7.8.0-cp312-cp312-win32.whl", hash = "sha256:769773614e676f9d8e8a0980dd7740f09a6ea386d0f383db6821df07d0f08545"}, - {file = "coverage-7.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:e5d2b9be5b0693cf21eb4ce0ec8d211efb43966f6657807f6859aab3814f946b"}, - {file = "coverage-7.8.0-pp39.pp310.pp311-none-any.whl", hash = "sha256:b8194fb8e50d556d5849753de991d390c5a1edeeba50f68e3a9253fbd8bf8ccd"}, - {file = "coverage-7.8.0-py3-none-any.whl", hash = "sha256:dbf364b4c5e7bae9250528167dfe40219b62e2d573c854d74be213e1e52069f7"}, - {file = "coverage-7.8.0.tar.gz", hash = "sha256:7a3d62b3b03b4b6fd41a085f3574874cf946cb4604d2b4d3e8dca8cd570ca501"}, -] - [[package]] name = "cryptography" -version = "44.0.2" +version = "45.0.7" requires_python = "!=3.9.0,!=3.9.1,>=3.7" summary = "cryptography is a package which provides cryptographic recipes and primitives to Python developers." groups = ["default"] dependencies = [ - "cffi>=1.12; platform_python_implementation != \"PyPy\"", -] -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-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"}, + "cffi>=1.14; platform_python_implementation != \"PyPy\"", +] +files = [ + {file = "cryptography-45.0.7-cp311-abi3-macosx_10_9_universal2.whl", hash = "sha256:3be4f21c6245930688bd9e162829480de027f8bf962ede33d4f8ba7d67a00cee"}, + {file = "cryptography-45.0.7-cp311-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:67285f8a611b0ebc0857ced2081e30302909f571a46bfa7a3cc0ad303fe015c6"}, + {file = "cryptography-45.0.7-cp311-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:577470e39e60a6cd7780793202e63536026d9b8641de011ed9d8174da9ca5339"}, + {file = "cryptography-45.0.7-cp311-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:4bd3e5c4b9682bc112d634f2c6ccc6736ed3635fc3319ac2bb11d768cc5a00d8"}, + {file = "cryptography-45.0.7-cp311-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:465ccac9d70115cd4de7186e60cfe989de73f7bb23e8a7aa45af18f7412e75bf"}, + {file = "cryptography-45.0.7-cp311-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:16ede8a4f7929b4b7ff3642eba2bf79aa1d71f24ab6ee443935c0d269b6bc513"}, + {file = "cryptography-45.0.7-cp311-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:8978132287a9d3ad6b54fcd1e08548033cc09dc6aacacb6c004c73c3eb5d3ac3"}, + {file = "cryptography-45.0.7-cp311-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:b6a0e535baec27b528cb07a119f321ac024592388c5681a5ced167ae98e9fff3"}, + {file = "cryptography-45.0.7-cp311-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:a24ee598d10befaec178efdff6054bc4d7e883f615bfbcd08126a0f4931c83a6"}, + {file = "cryptography-45.0.7-cp311-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:fa26fa54c0a9384c27fcdc905a2fb7d60ac6e47d14bc2692145f2b3b1e2cfdbd"}, + {file = "cryptography-45.0.7-cp311-abi3-win32.whl", hash = "sha256:bef32a5e327bd8e5af915d3416ffefdbe65ed975b646b3805be81b23580b57b8"}, + {file = "cryptography-45.0.7-cp311-abi3-win_amd64.whl", hash = "sha256:3808e6b2e5f0b46d981c24d79648e5c25c35e59902ea4391a0dcb3e667bf7443"}, + {file = "cryptography-45.0.7-cp37-abi3-macosx_10_9_universal2.whl", hash = "sha256:bfb4c801f65dd61cedfc61a83732327fafbac55a47282e6f26f073ca7a41c3b2"}, + {file = "cryptography-45.0.7-cp37-abi3-manylinux2014_aarch64.manylinux_2_17_aarch64.whl", hash = "sha256:81823935e2f8d476707e85a78a405953a03ef7b7b4f55f93f7c2d9680e5e0691"}, + {file = "cryptography-45.0.7-cp37-abi3-manylinux2014_x86_64.manylinux_2_17_x86_64.whl", hash = "sha256:3994c809c17fc570c2af12c9b840d7cea85a9fd3e5c0e0491f4fa3c029216d59"}, + {file = "cryptography-45.0.7-cp37-abi3-manylinux_2_28_aarch64.whl", hash = "sha256:dad43797959a74103cb59c5dac71409f9c27d34c8a05921341fb64ea8ccb1dd4"}, + {file = "cryptography-45.0.7-cp37-abi3-manylinux_2_28_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ce7a453385e4c4693985b4a4a3533e041558851eae061a58a5405363b098fcd3"}, + {file = "cryptography-45.0.7-cp37-abi3-manylinux_2_28_x86_64.whl", hash = "sha256:b04f85ac3a90c227b6e5890acb0edbaf3140938dbecf07bff618bf3638578cf1"}, + {file = "cryptography-45.0.7-cp37-abi3-manylinux_2_34_aarch64.whl", hash = "sha256:48c41a44ef8b8c2e80ca4527ee81daa4c527df3ecbc9423c41a420a9559d0e27"}, + {file = "cryptography-45.0.7-cp37-abi3-manylinux_2_34_x86_64.whl", hash = "sha256:f3df7b3d0f91b88b2106031fd995802a2e9ae13e02c36c1fc075b43f420f3a17"}, + {file = "cryptography-45.0.7-cp37-abi3-musllinux_1_2_aarch64.whl", hash = "sha256:dd342f085542f6eb894ca00ef70236ea46070c8a13824c6bde0dfdcd36065b9b"}, + {file = "cryptography-45.0.7-cp37-abi3-musllinux_1_2_x86_64.whl", hash = "sha256:1993a1bb7e4eccfb922b6cd414f072e08ff5816702a0bdb8941c247a6b1b287c"}, + {file = "cryptography-45.0.7-cp37-abi3-win32.whl", hash = "sha256:18fcf70f243fe07252dcb1b268a687f2358025ce32f9f88028ca5c364b123ef5"}, + {file = "cryptography-45.0.7-cp37-abi3-win_amd64.whl", hash = "sha256:7285a89df4900ed3bfaad5679b1e668cb4b38a8de1ccbfc84b05f34512da0a90"}, + {file = "cryptography-45.0.7-pp311-pypy311_pp73-macosx_10_9_x86_64.whl", hash = "sha256:4a862753b36620af6fc54209264f92c716367f2f0ff4624952276a6bbd18cbde"}, + {file = "cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_aarch64.whl", hash = "sha256:06ce84dc14df0bf6ea84666f958e6080cdb6fe1231be2a51f3fc1267d9f3fb34"}, + {file = "cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_28_x86_64.whl", hash = "sha256:d0c5c6bac22b177bf8da7435d9d27a6834ee130309749d162b26c3105c0795a9"}, + {file = "cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_aarch64.whl", hash = "sha256:2f641b64acc00811da98df63df7d59fd4706c0df449da71cb7ac39a0732b40ae"}, + {file = "cryptography-45.0.7-pp311-pypy311_pp73-manylinux_2_34_x86_64.whl", hash = "sha256:f5414a788ecc6ee6bc58560e85ca624258a55ca434884445440a810796ea0e0b"}, + {file = "cryptography-45.0.7-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:1f3d56f73595376f4244646dd5c5870c14c196949807be39e79e7bd9bac3da63"}, + {file = "cryptography-45.0.7.tar.gz", hash = "sha256:4b1654dfc64ea479c242508eb8c724044f1e964a47d1d1cacc5132292d851971"}, ] [[package]] name = "dnspython" -version = "2.7.0" -requires_python = ">=3.9" +version = "2.8.0" +requires_python = ">=3.10" summary = "DNS toolkit" groups = ["default"] files = [ - {file = "dnspython-2.7.0-py3-none-any.whl", hash = "sha256:b4c34b7d10b51bcc3a5071e7b8dee77939f1e878477eeecc965e9835f63c6c86"}, - {file = "dnspython-2.7.0.tar.gz", hash = "sha256:ce9c432eda0dc91cf618a5cedf1a4e142651196bbcd2c80e89ed5a907e5cfaf1"}, -] - -[[package]] -name = "flake8" -version = "7.2.0" -requires_python = ">=3.9" -summary = "the modular source code checker: pep8 pyflakes and co" -groups = ["dev"] -dependencies = [ - "mccabe<0.8.0,>=0.7.0", - "pycodestyle<2.14.0,>=2.13.0", - "pyflakes<3.4.0,>=3.3.0", -] -files = [ - {file = "flake8-7.2.0-py2.py3-none-any.whl", hash = "sha256:93b92ba5bdb60754a6da14fa3b93a9361fd00a59632ada61fd7b130436c40343"}, - {file = "flake8-7.2.0.tar.gz", hash = "sha256:fa558ae3f6f7dbf2b4f22663e5343b6b6023620461f8d4ff2019ef4b5ee70426"}, + {file = "dnspython-2.8.0-py3-none-any.whl", hash = "sha256:01d9bbc4a2d76bf0db7c1f729812ded6d912bd318d3b1cf81d30c0f845dbf3af"}, + {file = "dnspython-2.8.0.tar.gz", hash = "sha256:181d3c6996452cb1189c4046c61599b84a5a86e099562ffde77d26984ff26d0f"}, ] [[package]] name = "frozenlist" -version = "1.6.0" +version = "1.8.0" requires_python = ">=3.9" summary = "A list-like structure which implements collections.abc.MutableSequence" groups = ["default"] files = [ - {file = "frozenlist-1.6.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ae8337990e7a45683548ffb2fee1af2f1ed08169284cd829cdd9a7fa7470530d"}, - {file = "frozenlist-1.6.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:8c952f69dd524558694818a461855f35d36cc7f5c0adddce37e962c85d06eac0"}, - {file = "frozenlist-1.6.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:8f5fef13136c4e2dee91bfb9a44e236fff78fc2cd9f838eddfc470c3d7d90afe"}, - {file = "frozenlist-1.6.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:716bbba09611b4663ecbb7cd022f640759af8259e12a6ca939c0a6acd49eedba"}, - {file = "frozenlist-1.6.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:7b8c4dc422c1a3ffc550b465090e53b0bf4839047f3e436a34172ac67c45d595"}, - {file = "frozenlist-1.6.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b11534872256e1666116f6587a1592ef395a98b54476addb5e8d352925cb5d4a"}, - {file = "frozenlist-1.6.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1c6eceb88aaf7221f75be6ab498dc622a151f5f88d536661af3ffc486245a626"}, - {file = "frozenlist-1.6.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:62c828a5b195570eb4b37369fcbbd58e96c905768d53a44d13044355647838ff"}, - {file = "frozenlist-1.6.0-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e1c6bd2c6399920c9622362ce95a7d74e7f9af9bfec05fff91b8ce4b9647845a"}, - {file = "frozenlist-1.6.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:49ba23817781e22fcbd45fd9ff2b9b8cdb7b16a42a4851ab8025cae7b22e96d0"}, - {file = "frozenlist-1.6.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:431ef6937ae0f853143e2ca67d6da76c083e8b1fe3df0e96f3802fd37626e606"}, - {file = "frozenlist-1.6.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:9d124b38b3c299ca68433597ee26b7819209cb8a3a9ea761dfe9db3a04bba584"}, - {file = "frozenlist-1.6.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:118e97556306402e2b010da1ef21ea70cb6d6122e580da64c056b96f524fbd6a"}, - {file = "frozenlist-1.6.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:fb3b309f1d4086b5533cf7bbcf3f956f0ae6469664522f1bde4feed26fba60f1"}, - {file = "frozenlist-1.6.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:54dece0d21dce4fdb188a1ffc555926adf1d1c516e493c2914d7c370e454bc9e"}, - {file = "frozenlist-1.6.0-cp311-cp311-win32.whl", hash = "sha256:654e4ba1d0b2154ca2f096bed27461cf6160bc7f504a7f9a9ef447c293caf860"}, - {file = "frozenlist-1.6.0-cp311-cp311-win_amd64.whl", hash = "sha256:3e911391bffdb806001002c1f860787542f45916c3baf764264a52765d5a5603"}, - {file = "frozenlist-1.6.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:c5b9e42ace7d95bf41e19b87cec8f262c41d3510d8ad7514ab3862ea2197bfb1"}, - {file = "frozenlist-1.6.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:ca9973735ce9f770d24d5484dcb42f68f135351c2fc81a7a9369e48cf2998a29"}, - {file = "frozenlist-1.6.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6ac40ec76041c67b928ca8aaffba15c2b2ee3f5ae8d0cb0617b5e63ec119ca25"}, - {file = "frozenlist-1.6.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:95b7a8a3180dfb280eb044fdec562f9b461614c0ef21669aea6f1d3dac6ee576"}, - {file = "frozenlist-1.6.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:c444d824e22da6c9291886d80c7d00c444981a72686e2b59d38b285617cb52c8"}, - {file = "frozenlist-1.6.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:bb52c8166499a8150bfd38478248572c924c003cbb45fe3bcd348e5ac7c000f9"}, - {file = "frozenlist-1.6.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:b35298b2db9c2468106278537ee529719228950a5fdda686582f68f247d1dc6e"}, - {file = "frozenlist-1.6.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d108e2d070034f9d57210f22fefd22ea0d04609fc97c5f7f5a686b3471028590"}, - {file = "frozenlist-1.6.0-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:4e1be9111cb6756868ac242b3c2bd1f09d9aea09846e4f5c23715e7afb647103"}, - {file = "frozenlist-1.6.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:94bb451c664415f02f07eef4ece976a2c65dcbab9c2f1705b7031a3a75349d8c"}, - {file = "frozenlist-1.6.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:d1a686d0b0949182b8faddea596f3fc11f44768d1f74d4cad70213b2e139d821"}, - {file = "frozenlist-1.6.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:ea8e59105d802c5a38bdbe7362822c522230b3faba2aa35c0fa1765239b7dd70"}, - {file = "frozenlist-1.6.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:abc4e880a9b920bc5020bf6a431a6bb40589d9bca3975c980495f63632e8382f"}, - {file = "frozenlist-1.6.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9a79713adfe28830f27a3c62f6b5406c37376c892b05ae070906f07ae4487046"}, - {file = "frozenlist-1.6.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:9a0318c2068e217a8f5e3b85e35899f5a19e97141a45bb925bb357cfe1daf770"}, - {file = "frozenlist-1.6.0-cp312-cp312-win32.whl", hash = "sha256:853ac025092a24bb3bf09ae87f9127de9fe6e0c345614ac92536577cf956dfcc"}, - {file = "frozenlist-1.6.0-cp312-cp312-win_amd64.whl", hash = "sha256:2bdfe2d7e6c9281c6e55523acd6c2bf77963cb422fdc7d142fb0cb6621b66878"}, - {file = "frozenlist-1.6.0-py3-none-any.whl", hash = "sha256:535eec9987adb04701266b92745d6cdcef2e77669299359c3009c3404dd5d191"}, - {file = "frozenlist-1.6.0.tar.gz", hash = "sha256:b99655c32c1c8e06d111e7f41c06c29a5318cb1835df23a45518e02a47c63b68"}, + {file = "frozenlist-1.8.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:09474e9831bc2b2199fad6da3c14c7b0fbdd377cce9d3d77131be28906cb7d84"}, + {file = "frozenlist-1.8.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:17c883ab0ab67200b5f964d2b9ed6b00971917d5d8a92df149dc2c9779208ee9"}, + {file = "frozenlist-1.8.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fa47e444b8ba08fffd1c18e8cdb9a75db1b6a27f17507522834ad13ed5922b93"}, + {file = "frozenlist-1.8.0-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:2552f44204b744fba866e573be4c1f9048d6a324dfe14475103fd51613eb1d1f"}, + {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:957e7c38f250991e48a9a73e6423db1bb9dd14e722a10f6b8bb8e16a0f55f695"}, + {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:8585e3bb2cdea02fc88ffa245069c36555557ad3609e83be0ec71f54fd4abb52"}, + {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:edee74874ce20a373d62dc28b0b18b93f645633c2943fd90ee9d898550770581"}, + {file = "frozenlist-1.8.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:c9a63152fe95756b85f31186bddf42e4c02c6321207fd6601a1c89ebac4fe567"}, + {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:b6db2185db9be0a04fecf2f241c70b63b1a242e2805be291855078f2b404dd6b"}, + {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:f4be2e3d8bc8aabd566f8d5b8ba7ecc09249d74ba3c9ed52e54dc23a293f0b92"}, + {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:c8d1634419f39ea6f5c427ea2f90ca85126b54b50837f31497f3bf38266e853d"}, + {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:1a7fa382a4a223773ed64242dbe1c9c326ec09457e6b8428efb4118c685c3dfd"}, + {file = "frozenlist-1.8.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:11847b53d722050808926e785df837353bd4d75f1d494377e59b23594d834967"}, + {file = "frozenlist-1.8.0-cp311-cp311-win32.whl", hash = "sha256:27c6e8077956cf73eadd514be8fb04d77fc946a7fe9f7fe167648b0b9085cc25"}, + {file = "frozenlist-1.8.0-cp311-cp311-win_amd64.whl", hash = "sha256:ac913f8403b36a2c8610bbfd25b8013488533e71e62b4b4adce9c86c8cea905b"}, + {file = "frozenlist-1.8.0-cp311-cp311-win_arm64.whl", hash = "sha256:d4d3214a0f8394edfa3e303136d0575eece0745ff2b47bd2cb2e66dd92d4351a"}, + {file = "frozenlist-1.8.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:78f7b9e5d6f2fdb88cdde9440dc147259b62b9d3b019924def9f6478be254ac1"}, + {file = "frozenlist-1.8.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:229bf37d2e4acdaf808fd3f06e854a4a7a3661e871b10dc1f8f1896a3b05f18b"}, + {file = "frozenlist-1.8.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f833670942247a14eafbb675458b4e61c82e002a148f49e68257b79296e865c4"}, + {file = "frozenlist-1.8.0-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:494a5952b1c597ba44e0e78113a7266e656b9794eec897b19ead706bd7074383"}, + {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:96f423a119f4777a4a056b66ce11527366a8bb92f54e541ade21f2374433f6d4"}, + {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3462dd9475af2025c31cc61be6652dfa25cbfb56cbbf52f4ccfe029f38decaf8"}, + {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:c4c800524c9cd9bac5166cd6f55285957fcfc907db323e193f2afcd4d9abd69b"}, + {file = "frozenlist-1.8.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:d6a5df73acd3399d893dafc71663ad22534b5aa4f94e8a2fabfe856c3c1b6a52"}, + {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:405e8fe955c2280ce66428b3ca55e12b3c4e9c336fb2103a4937e891c69a4a29"}, + {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:908bd3f6439f2fef9e85031b59fd4f1297af54415fb60e4254a95f75b3cab3f3"}, + {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:294e487f9ec720bd8ffcebc99d575f7eff3568a08a253d1ee1a0378754b74143"}, + {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:74c51543498289c0c43656701be6b077f4b265868fa7f8a8859c197006efb608"}, + {file = "frozenlist-1.8.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:776f352e8329135506a1d6bf16ac3f87bc25b28e765949282dcc627af36123aa"}, + {file = "frozenlist-1.8.0-cp312-cp312-win32.whl", hash = "sha256:433403ae80709741ce34038da08511d4a77062aa924baf411ef73d1146e74faf"}, + {file = "frozenlist-1.8.0-cp312-cp312-win_amd64.whl", hash = "sha256:34187385b08f866104f0c0617404c8eb08165ab1272e884abc89c112e9c00746"}, + {file = "frozenlist-1.8.0-cp312-cp312-win_arm64.whl", hash = "sha256:fe3c58d2f5db5fbd18c2987cba06d51b0529f52bc3a6cdc33d3f4eab725104bd"}, + {file = "frozenlist-1.8.0-py3-none-any.whl", hash = "sha256:0c18a16eab41e82c295618a77502e17b195883241c563b00f0aa5106fc4eaa0d"}, + {file = "frozenlist-1.8.0.tar.gz", hash = "sha256:3ede829ed8d842f6cd48fc7081d7a41001a56f1f38603f9d49bf3020d59a31ad"}, ] [[package]] name = "h11" -version = "0.14.0" -requires_python = ">=3.7" +version = "0.16.0" +requires_python = ">=3.8" summary = "A pure-Python, bring-your-own-I/O implementation of HTTP/1.1" groups = ["default"] -dependencies = [ - "typing-extensions; python_version < \"3.8\"", -] files = [ - {file = "h11-0.14.0-py3-none-any.whl", hash = "sha256:e3fe4ac4b851c468cc8363d500db52c2ead036020723024a109d37346efaa761"}, - {file = "h11-0.14.0.tar.gz", hash = "sha256:8f19fbbe99e72420ff35c00b27a34cb9937e902a8b810e2c88300c6f0a3b699d"}, + {file = "h11-0.16.0-py3-none-any.whl", hash = "sha256:63cf8bbe7522de3bf65932fda1d9c2772064ffb3dae62d55932da54b31cb6c86"}, + {file = "h11-0.16.0.tar.gz", hash = "sha256:4e35b956cf45792e4caa5885e69fba00bdbc6ffafbfa020300e549b208ee5ff1"}, ] [[package]] name = "httpcore" -version = "1.0.8" +version = "1.0.9" requires_python = ">=3.8" summary = "A minimal low-level HTTP client." groups = ["default"] dependencies = [ "certifi", - "h11<0.15,>=0.13", + "h11>=0.16", ] files = [ - {file = "httpcore-1.0.8-py3-none-any.whl", hash = "sha256:5254cf149bcb5f75e9d1b2b9f729ea4a4b883d1ad7379fc632b727cec23674be"}, - {file = "httpcore-1.0.8.tar.gz", hash = "sha256:86e94505ed24ea06514883fd44d2bc02d90e77e7979c8eb71b90f41d364a1bad"}, + {file = "httpcore-1.0.9-py3-none-any.whl", hash = "sha256:2d400746a40668fc9dec9810239072b40b4484b640a8c38fd654a024c7a1bf55"}, + {file = "httpcore-1.0.9.tar.gz", hash = "sha256:6e34463af53fd2ab5d807f399a9b45ea31c3dfa2276f15a2c3f00afff6e176e8"}, ] [[package]] @@ -604,38 +517,13 @@ files = [ [[package]] name = "idna" -version = "3.10" -requires_python = ">=3.6" -summary = "Internationalized Domain Names in Applications (IDNA)" -groups = ["default"] -files = [ - {file = "idna-3.10-py3-none-any.whl", hash = "sha256:946d195a0d259cbba61165e88e65941f16e9b36ea6ddb97f00452bae8b1287d3"}, - {file = "idna-3.10.tar.gz", hash = "sha256:12f65c9b470abda6dc35cf8e63cc574b1c52b11df2c86030af0ac09b01b13ea9"}, -] - -[[package]] -name = "iniconfig" -version = "2.1.0" +version = "3.11" requires_python = ">=3.8" -summary = "brain-dead simple config-ini parsing" -groups = ["dev"] -files = [ - {file = "iniconfig-2.1.0-py3-none-any.whl", hash = "sha256:9deba5723312380e77435581c6bf4935c94cbfab9b1ed33ef8d238ea168eb760"}, - {file = "iniconfig-2.1.0.tar.gz", hash = "sha256:3abbd2e30b36733fee78f9c7f7308f2d0050e88f0087fd25c2645f63c773e1c7"}, -] - -[[package]] -name = "jinja2" -version = "3.1.6" -requires_python = ">=3.7" -summary = "A very fast and expressive template engine." +summary = "Internationalized Domain Names in Applications (IDNA)" groups = ["default"] -dependencies = [ - "MarkupSafe>=2.0", -] files = [ - {file = "jinja2-3.1.6-py3-none-any.whl", hash = "sha256:85ece4451f492d0c13c5dd7c13a64681a86afae63a5f347908daf103ce6d2f67"}, - {file = "jinja2-3.1.6.tar.gz", hash = "sha256:0137fb05990d35f1275a587e9aee6d56da821fc83491a0fb838183be43f66d6d"}, + {file = "idna-3.11-py3-none-any.whl", hash = "sha256:771a87f49d9defaf64091e6e6fe9c18d4833f140bd19464795bc32d966ca37ea"}, + {file = "idna-3.11.tar.gz", hash = "sha256:795dafcc9c04ed0c1fb032c2aa73654d8e8c5023a7df64a53f39190ada629902"}, ] [[package]] @@ -651,84 +539,51 @@ files = [ [[package]] name = "libipld" -version = "3.0.1" +version = "3.1.1" requires_python = ">=3.8" summary = "Python binding to the Rust IPLD library" groups = ["default"] files = [ - {file = "libipld-3.0.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:3f9bf02d065c4833936c274417282e52bf626924dd4f943a3c97095a5571d400"}, - {file = "libipld-3.0.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:2049735348bf827818a3856e9ca9e0e2d5a961018a29c7369363cd06252156ad"}, - {file = "libipld-3.0.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:05c7b666ea6ac9b63bd8148051a560e5c1e7352d48e334299b1a03ed0d7c3749"}, - {file = "libipld-3.0.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:8ae0334e5dbb93d6e56f7eed66f24e46e7066553ec9c55cd229848b7b15d6b30"}, - {file = "libipld-3.0.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:edc249291665665a38c4d25afa279082ff2da9d0bbbd0e9f865df6a02580a74a"}, - {file = "libipld-3.0.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1bca61abec0ea8d6044a06c044c31f23f3acf44d9ced0c35650c31824255344e"}, - {file = "libipld-3.0.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b45f04c8426e08d5be9f648cc3c8c4625e9de66d7d9bbb191ff477ebf87f2921"}, - {file = "libipld-3.0.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7a39bb7db97c7335c77c16723d7cac69e128b0d9792c5dd61101b65e3a084d1f"}, - {file = "libipld-3.0.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:cd93e321bdc50253a817d39d5777f999b0f08733cd4feee70116a2b0f55dc1f4"}, - {file = "libipld-3.0.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:cb7862704ff71d1fd359ffef6f795eb83463a58c904237ef447206e4772d5412"}, - {file = "libipld-3.0.1-cp311-cp311-win32.whl", hash = "sha256:7a6122fad76d604c277f5690a4d41509a5b3c71f0c7d9fd0cc7c80672aa34402"}, - {file = "libipld-3.0.1-cp311-cp311-win_amd64.whl", hash = "sha256:8773a3e359d345dc5f96df8812da0e83fba37e7edec630e1836f78ac02c6c613"}, - {file = "libipld-3.0.1-cp311-cp311-win_arm64.whl", hash = "sha256:9701d770111b0b64949b957d432df693c9a7b2a4a348c0627e4db43ade60e3aa"}, - {file = "libipld-3.0.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:27313adb70ca9ecfaaa34f1ca6e45ee0569935b7ba9802f78c2f37f7a633a7dd"}, - {file = "libipld-3.0.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:bf5a14647350aa6779d634b7dc0f6967296fe52e9ca1d6132e24aa388c77c68e"}, - {file = "libipld-3.0.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:3d9e619573d500eb4a4ab4a8ef90882305fba43a5a405eb80fcc0afe5d6e9dcd"}, - {file = "libipld-3.0.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a2fbfaed3fc98c95cd412e61e960cd41633fc880de24327613b0cb0b974d277b"}, - {file = "libipld-3.0.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:b36044476920455a26d30df75728eab069201c42c0af3e3610a30fd62b96ab55"}, - {file = "libipld-3.0.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4586a3442f12065a64a36ae56d80c71d05a87413fbf17bae330c42793c8ecfac"}, - {file = "libipld-3.0.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d243ca7dea89e1579fd95f95ff612a7b56a980743c25e2a0b1a39cae7b67e55e"}, - {file = "libipld-3.0.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:1525c07363abb20e8cd416df7ca316ddfc4f592ed2da694b02e0e4a4af1b9418"}, - {file = "libipld-3.0.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:372768df5540867962c3c16fe80976f8b162a9771e8fe1b2175f18dabf23b9ce"}, - {file = "libipld-3.0.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:47bf15f9fc5890ff4807c0c5cb0ff99d625bcea3cd222aaa500d57466da529bd"}, - {file = "libipld-3.0.1-cp312-cp312-win32.whl", hash = "sha256:989d37ae0cb31380e6b76391e0272342de830adad2821c2de7b925b360fc45f3"}, - {file = "libipld-3.0.1-cp312-cp312-win_amd64.whl", hash = "sha256:4557f20d4b8e61ac6c89ab4cea04f3a518a266f3c3d7348cf4cc8ac9b02c89dc"}, - {file = "libipld-3.0.1-cp312-cp312-win_arm64.whl", hash = "sha256:92ec97dac2e978f09343ebb64b0bb9bed9c294e8a224490552cfc200e9101f5c"}, - {file = "libipld-3.0.1.tar.gz", hash = "sha256:2970752de70e5fdcac4646900cdefaa0dca08db9b5d59c40b5496d99e3bffa64"}, -] - -[[package]] -name = "markupsafe" -version = "3.0.2" -requires_python = ">=3.9" -summary = "Safely add untrusted strings to HTML/XML markup." -groups = ["default"] -files = [ - {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:9025b4018f3a1314059769c7bf15441064b2207cb3f065e6ea1e7359cb46db9d"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:93335ca3812df2f366e80509ae119189886b0f3c2b81325d39efdb84a1e2ae93"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2cb8438c3cbb25e220c2ab33bb226559e7afb3baec11c4f218ffa7308603c832"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:a123e330ef0853c6e822384873bef7507557d8e4a082961e1defa947aa59ba84"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:1e084f686b92e5b83186b07e8a17fc09e38fff551f3602b249881fec658d3eca"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8213e09c917a951de9d09ecee036d5c7d36cb6cb7dbaece4c71a60d79fb9798"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:5b02fb34468b6aaa40dfc198d813a641e3a63b98c2b05a16b9f80b7ec314185e"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:0bff5e0ae4ef2e1ae4fdf2dfd5b76c75e5c2fa4132d05fc1b0dabcd20c7e28c4"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-win32.whl", hash = "sha256:6c89876f41da747c8d3677a2b540fb32ef5715f97b66eeb0c6b66f5e3ef6f59d"}, - {file = "MarkupSafe-3.0.2-cp311-cp311-win_amd64.whl", hash = "sha256:70a87b411535ccad5ef2f1df5136506a10775d267e197e4cf531ced10537bd6b"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:9778bd8ab0a994ebf6f84c2b949e65736d5575320a17ae8984a77fab08db94cf"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:846ade7b71e3536c4e56b386c2a47adf5741d2d8b94ec9dc3e92e5e1ee1e2225"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:1c99d261bd2d5f6b59325c92c73df481e05e57f19837bdca8413b9eac4bd8028"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:e17c96c14e19278594aa4841ec148115f9c7615a47382ecb6b82bd8fea3ab0c8"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:88416bd1e65dcea10bc7569faacb2c20ce071dd1f87539ca2ab364bf6231393c"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:2181e67807fc2fa785d0592dc2d6206c019b9502410671cc905d132a92866557"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:52305740fe773d09cffb16f8ed0427942901f00adedac82ec8b67752f58a1b22"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ad10d3ded218f1039f11a75f8091880239651b52e9bb592ca27de44eed242a48"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-win32.whl", hash = "sha256:0f4ca02bea9a23221c0182836703cbf8930c5e9454bacce27e767509fa286a30"}, - {file = "MarkupSafe-3.0.2-cp312-cp312-win_amd64.whl", hash = "sha256:8e06879fc22a25ca47312fbe7c8264eb0b662f6db27cb2d3bbbc74b1df4b9b87"}, - {file = "markupsafe-3.0.2.tar.gz", hash = "sha256:ee55d3edf80167e48ea11a923c7386f4669df67d7994554387f84e7d8b0a2bf0"}, -] - -[[package]] -name = "mccabe" -version = "0.7.0" -requires_python = ">=3.6" -summary = "McCabe checker, plugin for flake8" -groups = ["dev"] -files = [ - {file = "mccabe-0.7.0-py2.py3-none-any.whl", hash = "sha256:6c2d30ab6be0e4a46919781807b4f0d834ebdd6c6e3dca0bda5a15f863427b6e"}, - {file = "mccabe-0.7.0.tar.gz", hash = "sha256:348e0240c33b60bbdf4e523192ef919f28cb2c3d7d5c7794f74009290f236325"}, + {file = "libipld-3.1.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:e08ac2f957b06f96dd32b9a8a58a1f0724fd25867d144b638b9dcf1b712d8f28"}, + {file = "libipld-3.1.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a69e13b14d6e259e84ffa28e0c125ad490f7f0faab91dcce3a6a81296c083adb"}, + {file = "libipld-3.1.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5597d25244bf2a2826019649828df69d385872cb807bbed2737dc1d4442fc2b3"}, + {file = "libipld-3.1.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:d42613124b21fd68583472be883ec1ec6c9d9b96b6fb56edffa4c94c422200d7"}, + {file = "libipld-3.1.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9ccb0f4dd1a0468fcd24925664e4df266f79d76497233e00634f5309ed96fdbc"}, + {file = "libipld-3.1.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:44a18f5eb1785b45f174bb589210f800f77dfe75fd5e074465661600e586545d"}, + {file = "libipld-3.1.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4f72c4885da636b51953059e89f669f6bda70618b895ddbbce8c0c3cf04a8af"}, + {file = "libipld-3.1.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:dae236dac7d289020734e9f53666ab51b93f851ee76767cd6203c39c4cea7f77"}, + {file = "libipld-3.1.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:08e72009c20bf0698a6390cef5726dbba0f977b679e0365289f2cfba5b7a0396"}, + {file = "libipld-3.1.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:e56c10b19194f357d52acd72d2da35eb5c6ed1ab96454baad981ab67271d868a"}, + {file = "libipld-3.1.1-cp311-cp311-win32.whl", hash = "sha256:333c5d4a75dc35918d2d8d3fc0883d9e5e2a621e39cd06779708b938b0d1350a"}, + {file = "libipld-3.1.1-cp311-cp311-win_amd64.whl", hash = "sha256:ead4e5c3941a5167caa7d6ed789d58da81ec7d992c822c2552f82fa097615b02"}, + {file = "libipld-3.1.1-cp311-cp311-win_arm64.whl", hash = "sha256:06f8abe5273609b7a29ec10797f7c83366f91c6f3bddfb93ef92a519f6da3e41"}, + {file = "libipld-3.1.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:27d2fb2b19a9784a932a41fd1a6942361cfa65e0957871f4bde06c81639a32b1"}, + {file = "libipld-3.1.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:7f0156a9bf04b7f575b907b7a15b902dde2d8af129aeb161b3ab6940f3fd9c02"}, + {file = "libipld-3.1.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:29cf371122648a688f87fe3307bcfe2c6a4aefa184ba44126f066975cfd26b46"}, + {file = "libipld-3.1.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:a5463672cd0708d47bc8cfe1cc0dd95c55d5b7f3947027e0e9c6a13b1dc1b6d0"}, + {file = "libipld-3.1.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:27a1b9b9392679fb494214bfa350adf7447b43bc39e497b669307da1f6dc8dd5"}, + {file = "libipld-3.1.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a83d944c71ed50772a7cef3f14e3ef3cf93145c82963b9e49a85cd9ee0ba9878"}, + {file = "libipld-3.1.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:cb9fef573406f7134727e0561e42fd221721800ed01d47f1207916595b72e780"}, + {file = "libipld-3.1.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:485b21bdddbe7a3bb8f33f1d0b9998343bd82a578406e31f85899b031602d34d"}, + {file = "libipld-3.1.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:4fe6fa67a242755773f3e960163010bdbc797316ca782d387e6b128e0d3bca19"}, + {file = "libipld-3.1.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:38298cbea4f8308bb848c7f8c3d8e41cd2c9235ef8bca6adefd2a002e94287ff"}, + {file = "libipld-3.1.1-cp312-cp312-win32.whl", hash = "sha256:1bc228298e249baac85f702da7d1e23ee429529a078a6bdf09570168f53fcb0f"}, + {file = "libipld-3.1.1-cp312-cp312-win_amd64.whl", hash = "sha256:a393e1809c7b1aa67c6f6c5d701787298f507448a601b8ec825b6ae26084fbad"}, + {file = "libipld-3.1.1-cp312-cp312-win_arm64.whl", hash = "sha256:7ad7870d2ee609d74eec4ba6dbc2caef0357861b3e0944226272f0e91f016d37"}, + {file = "libipld-3.1.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:5c596ce28eb5a5e0f072e8e58227bed1812d9aaee84708aa39ad84bb9888ad18"}, + {file = "libipld-3.1.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:40dde6adb9d5a350111e8f98915f1b8d0697d7842cdcc16f500db7b82d1814bd"}, + {file = "libipld-3.1.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:7d0ab0d74943bec5b02d4e71394c6a94171d9fb021672cef6e9ceee5c2204a63"}, + {file = "libipld-3.1.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bfd76ac468c35ae07a45b59be16fff4dc06b1eb8683d11dfaf8996ef3fa99614"}, + {file = "libipld-3.1.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:7c3143e899e414a0eae80b92e2e947a90caee7e060b0e5e8bb584df85f639a99"}, + {file = "libipld-3.1.1-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:8f71f67669c1ac1baf2f9e9d7f738be08d7bb810987a21b9d34778063523364f"}, + {file = "libipld-3.1.1-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:600c9a82a356ebf32532fd8ae5567a8431dcb820efe84da30a91a3e1303d6319"}, + {file = "libipld-3.1.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:65a5b20fa065a18d8ab2d0d3164c8f1ef3c18b38bf5c671664ff5a746a5e459a"}, + {file = "libipld-3.1.1.tar.gz", hash = "sha256:4b9a9da0ea5d848e9fa12c700027619a1e37ecc1da39dbd1424c0e9062f29e44"}, ] [[package]] name = "multidict" -version = "6.4.3" +version = "6.7.0" requires_python = ">=3.9" summary = "multidict implementation" groups = ["default"] @@ -736,235 +591,179 @@ dependencies = [ "typing-extensions>=4.1.0; python_version < \"3.11\"", ] files = [ - {file = "multidict-6.4.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:f6f19170197cc29baccd33ccc5b5d6a331058796485857cf34f7635aa25fb0cd"}, - {file = "multidict-6.4.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:f2882bf27037eb687e49591690e5d491e677272964f9ec7bc2abbe09108bdfb8"}, - {file = "multidict-6.4.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:fbf226ac85f7d6b6b9ba77db4ec0704fde88463dc17717aec78ec3c8546c70ad"}, - {file = "multidict-6.4.3-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:2e329114f82ad4b9dd291bef614ea8971ec119ecd0f54795109976de75c9a852"}, - {file = "multidict-6.4.3-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:1f4e0334d7a555c63f5c8952c57ab6f1c7b4f8c7f3442df689fc9f03df315c08"}, - {file = "multidict-6.4.3-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:740915eb776617b57142ce0bb13b7596933496e2f798d3d15a20614adf30d229"}, - {file = "multidict-6.4.3-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:255dac25134d2b141c944b59a0d2f7211ca12a6d4779f7586a98b4b03ea80508"}, - {file = "multidict-6.4.3-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d4e8535bd4d741039b5aad4285ecd9b902ef9e224711f0b6afda6e38d7ac02c7"}, - {file = "multidict-6.4.3-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:30c433a33be000dd968f5750722eaa0991037be0be4a9d453eba121774985bc8"}, - {file = "multidict-6.4.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:4eb33b0bdc50acd538f45041f5f19945a1f32b909b76d7b117c0c25d8063df56"}, - {file = "multidict-6.4.3-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:75482f43465edefd8a5d72724887ccdcd0c83778ded8f0cb1e0594bf71736cc0"}, - {file = "multidict-6.4.3-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:ce5b3082e86aee80b3925ab4928198450d8e5b6466e11501fe03ad2191c6d777"}, - {file = "multidict-6.4.3-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e413152e3212c4d39f82cf83c6f91be44bec9ddea950ce17af87fbf4e32ca6b2"}, - {file = "multidict-6.4.3-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:8aac2eeff69b71f229a405c0a4b61b54bade8e10163bc7b44fcd257949620618"}, - {file = "multidict-6.4.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:ab583ac203af1d09034be41458feeab7863c0635c650a16f15771e1386abf2d7"}, - {file = "multidict-6.4.3-cp311-cp311-win32.whl", hash = "sha256:1b2019317726f41e81154df636a897de1bfe9228c3724a433894e44cd2512378"}, - {file = "multidict-6.4.3-cp311-cp311-win_amd64.whl", hash = "sha256:43173924fa93c7486402217fab99b60baf78d33806af299c56133a3755f69589"}, - {file = "multidict-6.4.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:1f1c2f58f08b36f8475f3ec6f5aeb95270921d418bf18f90dffd6be5c7b0e676"}, - {file = "multidict-6.4.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:26ae9ad364fc61b936fb7bf4c9d8bd53f3a5b4417142cd0be5c509d6f767e2f1"}, - {file = "multidict-6.4.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:659318c6c8a85f6ecfc06b4e57529e5a78dfdd697260cc81f683492ad7e9435a"}, - {file = "multidict-6.4.3-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:e1eb72c741fd24d5a28242ce72bb61bc91f8451877131fa3fe930edb195f7054"}, - {file = "multidict-6.4.3-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3cd06d88cb7398252284ee75c8db8e680aa0d321451132d0dba12bc995f0adcc"}, - {file = "multidict-6.4.3-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:4543d8dc6470a82fde92b035a92529317191ce993533c3c0c68f56811164ed07"}, - {file = "multidict-6.4.3-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:30a3ebdc068c27e9d6081fca0e2c33fdf132ecea703a72ea216b81a66860adde"}, - {file = "multidict-6.4.3-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:b038f10e23f277153f86f95c777ba1958bcd5993194fda26a1d06fae98b2f00c"}, - {file = "multidict-6.4.3-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:c605a2b2dc14282b580454b9b5d14ebe0668381a3a26d0ac39daa0ca115eb2ae"}, - {file = "multidict-6.4.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:8bd2b875f4ca2bb527fe23e318ddd509b7df163407b0fb717df229041c6df5d3"}, - {file = "multidict-6.4.3-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:c2e98c840c9c8e65c0e04b40c6c5066c8632678cd50c8721fdbcd2e09f21a507"}, - {file = "multidict-6.4.3-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:66eb80dd0ab36dbd559635e62fba3083a48a252633164857a1d1684f14326427"}, - {file = "multidict-6.4.3-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:c23831bdee0a2a3cf21be057b5e5326292f60472fb6c6f86392bbf0de70ba731"}, - {file = "multidict-6.4.3-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:1535cec6443bfd80d028052e9d17ba6ff8a5a3534c51d285ba56c18af97e9713"}, - {file = "multidict-6.4.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3b73e7227681f85d19dec46e5b881827cd354aabe46049e1a61d2f9aaa4e285a"}, - {file = "multidict-6.4.3-cp312-cp312-win32.whl", hash = "sha256:8eac0c49df91b88bf91f818e0a24c1c46f3622978e2c27035bfdca98e0e18124"}, - {file = "multidict-6.4.3-cp312-cp312-win_amd64.whl", hash = "sha256:11990b5c757d956cd1db7cb140be50a63216af32cd6506329c2c59d732d802db"}, - {file = "multidict-6.4.3-py3-none-any.whl", hash = "sha256:59fe01ee8e2a1e8ceb3f6dbb216b09c8d9f4ef1c22c4fc825d045a147fa2ebc9"}, - {file = "multidict-6.4.3.tar.gz", hash = "sha256:3ada0b058c9f213c5f95ba301f922d402ac234f1111a7d8fd70f1b99f3c281ec"}, -] - -[[package]] -name = "mypy-extensions" -version = "1.1.0" -requires_python = ">=3.8" -summary = "Type system extensions for programs checked with the mypy type checker." -groups = ["dev"] -files = [ - {file = "mypy_extensions-1.1.0-py3-none-any.whl", hash = "sha256:1be4cccdb0f2482337c4743e60421de3a356cd97508abadd57d47403e94f5505"}, - {file = "mypy_extensions-1.1.0.tar.gz", hash = "sha256:52e68efc3284861e772bbcd66823fde5ae21fd2fdb51c62a211403730b916558"}, -] - -[[package]] -name = "packaging" -version = "25.0" -requires_python = ">=3.8" -summary = "Core utilities for Python packages" -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 = "pathspec" -version = "0.12.1" -requires_python = ">=3.8" -summary = "Utility library for gitignore style pattern matching of file paths." -groups = ["dev"] -files = [ - {file = "pathspec-0.12.1-py3-none-any.whl", hash = "sha256:a0d503e138a4c123b27490a4f7beda6a01c6f288df0e4a8b79c7eb0dc7b4cc08"}, - {file = "pathspec-0.12.1.tar.gz", hash = "sha256:a482d51503a1ab33b1c67a6c3813a26953dbdc71c31dacaef9a838c4e29f5712"}, -] - -[[package]] -name = "platformdirs" -version = "4.3.7" + {file = "multidict-6.7.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:4d409aa42a94c0b3fa617708ef5276dfe81012ba6753a0370fcc9d0195d0a1fc"}, + {file = "multidict-6.7.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:14c9e076eede3b54c636f8ce1c9c252b5f057c62131211f0ceeec273810c9721"}, + {file = "multidict-6.7.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:4c09703000a9d0fa3c3404b27041e574cc7f4df4c6563873246d0e11812a94b6"}, + {file = "multidict-6.7.0-cp311-cp311-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:a265acbb7bb33a3a2d626afbe756371dce0279e7b17f4f4eda406459c2b5ff1c"}, + {file = "multidict-6.7.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:51cb455de290ae462593e5b1cb1118c5c22ea7f0d3620d9940bf695cea5a4bd7"}, + {file = "multidict-6.7.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:db99677b4457c7a5c5a949353e125ba72d62b35f74e26da141530fbb012218a7"}, + {file = "multidict-6.7.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:f470f68adc395e0183b92a2f4689264d1ea4b40504a24d9882c27375e6662bb9"}, + {file = "multidict-6.7.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0db4956f82723cc1c270de9c6e799b4c341d327762ec78ef82bb962f79cc07d8"}, + {file = "multidict-6.7.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:3e56d780c238f9e1ae66a22d2adf8d16f485381878250db8d496623cd38b22bd"}, + {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:9d14baca2ee12c1a64740d4531356ba50b82543017f3ad6de0deb943c5979abb"}, + {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:295a92a76188917c7f99cda95858c822f9e4aae5824246bba9b6b44004ddd0a6"}, + {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:39f1719f57adbb767ef592a50ae5ebb794220d1188f9ca93de471336401c34d2"}, + {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:0a13fb8e748dfc94749f622de065dd5c1def7e0d2216dba72b1d8069a389c6ff"}, + {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e3aa16de190d29a0ea1b48253c57d99a68492c8dd8948638073ab9e74dc9410b"}, + {file = "multidict-6.7.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:a048ce45dcdaaf1defb76b2e684f997fb5abf74437b6cb7b22ddad934a964e34"}, + {file = "multidict-6.7.0-cp311-cp311-win32.whl", hash = "sha256:a90af66facec4cebe4181b9e62a68be65e45ac9b52b67de9eec118701856e7ff"}, + {file = "multidict-6.7.0-cp311-cp311-win_amd64.whl", hash = "sha256:95b5ffa4349df2887518bb839409bcf22caa72d82beec453216802f475b23c81"}, + {file = "multidict-6.7.0-cp311-cp311-win_arm64.whl", hash = "sha256:329aa225b085b6f004a4955271a7ba9f1087e39dcb7e65f6284a988264a63912"}, + {file = "multidict-6.7.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:8a3862568a36d26e650a19bb5cbbba14b71789032aebc0423f8cc5f150730184"}, + {file = "multidict-6.7.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:960c60b5849b9b4f9dcc9bea6e3626143c252c74113df2c1540aebce70209b45"}, + {file = "multidict-6.7.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:2049be98fb57a31b4ccf870bf377af2504d4ae35646a19037ec271e4c07998aa"}, + {file = "multidict-6.7.0-cp312-cp312-manylinux1_i686.manylinux_2_28_i686.manylinux_2_5_i686.whl", hash = "sha256:0934f3843a1860dd465d38895c17fce1f1cb37295149ab05cd1b9a03afacb2a7"}, + {file = "multidict-6.7.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:b3e34f3a1b8131ba06f1a73adab24f30934d148afcd5f5de9a73565a4404384e"}, + {file = "multidict-6.7.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:efbb54e98446892590dc2458c19c10344ee9a883a79b5cec4bc34d6656e8d546"}, + {file = "multidict-6.7.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a35c5fc61d4f51eb045061e7967cfe3123d622cd500e8868e7c0c592a09fedc4"}, + {file = "multidict-6.7.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:29fe6740ebccba4175af1b9b87bf553e9c15cd5868ee967e010efcf94e4fd0f1"}, + {file = "multidict-6.7.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:123e2a72e20537add2f33a79e605f6191fba2afda4cbb876e35c1a7074298a7d"}, + {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:b284e319754366c1aee2267a2036248b24eeb17ecd5dc16022095e747f2f4304"}, + {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:803d685de7be4303b5a657b76e2f6d1240e7e0a8aa2968ad5811fa2285553a12"}, + {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:c04a328260dfd5db8c39538f999f02779012268f54614902d0afc775d44e0a62"}, + {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:8a19cdb57cd3df4cd865849d93ee14920fb97224300c88501f16ecfa2604b4e0"}, + {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:9b2fd74c52accced7e75de26023b7dccee62511a600e62311b918ec5c168fc2a"}, + {file = "multidict-6.7.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:3e8bfdd0e487acf992407a140d2589fe598238eaeffa3da8448d63a63cd363f8"}, + {file = "multidict-6.7.0-cp312-cp312-win32.whl", hash = "sha256:dd32a49400a2c3d52088e120ee00c1e3576cbff7e10b98467962c74fdb762ed4"}, + {file = "multidict-6.7.0-cp312-cp312-win_amd64.whl", hash = "sha256:92abb658ef2d7ef22ac9f8bb88e8b6c3e571671534e029359b6d9e845923eb1b"}, + {file = "multidict-6.7.0-cp312-cp312-win_arm64.whl", hash = "sha256:490dab541a6a642ce1a9d61a4781656b346a55c13038f0b1244653828e3a83ec"}, + {file = "multidict-6.7.0-py3-none-any.whl", hash = "sha256:394fc5c42a333c9ffc3e421a4c85e08580d990e08b99f6bf35b4132114c5dcb3"}, + {file = "multidict-6.7.0.tar.gz", hash = "sha256:c6e99d9a65ca282e578dfea819cfa9c0a62b2499d8677392e09feaf305e9e6f5"}, +] + +[[package]] +name = "prometheus-client" +version = "0.23.1" requires_python = ">=3.9" -summary = "A small Python package for determining appropriate platform-specific dirs, e.g. a `user data dir`." -groups = ["dev"] -files = [ - {file = "platformdirs-4.3.7-py3-none-any.whl", hash = "sha256:a03875334331946f13c549dbd8f4bac7a13a50a895a0eb1e8c6a8ace80d40a94"}, - {file = "platformdirs-4.3.7.tar.gz", hash = "sha256:eb437d586b6a0986388f0d6f74aa0cde27b48d0e3d66843640bfb6bdcdb6e351"}, -] - -[[package]] -name = "pluggy" -version = "1.5.0" -requires_python = ">=3.8" -summary = "plugin and hook calling mechanisms for python" -groups = ["dev"] +summary = "Python client for the Prometheus monitoring system." +groups = ["default"] files = [ - {file = "pluggy-1.5.0-py3-none-any.whl", hash = "sha256:44e1ad92c8ca002de6377e165f3e0f1be63266ab4d554740532335b9d75ea669"}, - {file = "pluggy-1.5.0.tar.gz", hash = "sha256:2cffa88e94fdc978c4c574f15f9e59b7f4201d439195c3715ca9e2486f1d0cf1"}, + {file = "prometheus_client-0.23.1-py3-none-any.whl", hash = "sha256:dd1913e6e76b59cfe44e7a4b83e01afc9873c1bdfd2ed8739f1e76aeca115f99"}, + {file = "prometheus_client-0.23.1.tar.gz", hash = "sha256:6ae8f9081eaaaf153a2e959d2e6c4f4fb57b12ef76c8c7980202f1e57b48b2ce"}, ] [[package]] name = "propcache" -version = "0.3.1" +version = "0.4.1" requires_python = ">=3.9" summary = "Accelerated property cache" groups = ["default"] files = [ - {file = "propcache-0.3.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:7f30241577d2fef2602113b70ef7231bf4c69a97e04693bde08ddab913ba0ce5"}, - {file = "propcache-0.3.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:43593c6772aa12abc3af7784bff4a41ffa921608dd38b77cf1dfd7f5c4e71371"}, - {file = "propcache-0.3.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:a75801768bbe65499495660b777e018cbe90c7980f07f8aa57d6be79ea6f71da"}, - {file = "propcache-0.3.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:f6f1324db48f001c2ca26a25fa25af60711e09b9aaf4b28488602776f4f9a744"}, - {file = "propcache-0.3.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5cdb0f3e1eb6dfc9965d19734d8f9c481b294b5274337a8cb5cb01b462dcb7e0"}, - {file = "propcache-0.3.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:1eb34d90aac9bfbced9a58b266f8946cb5935869ff01b164573a7634d39fbcb5"}, - {file = "propcache-0.3.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f35c7070eeec2cdaac6fd3fe245226ed2a6292d3ee8c938e5bb645b434c5f256"}, - {file = "propcache-0.3.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b23c11c2c9e6d4e7300c92e022046ad09b91fd00e36e83c44483df4afa990073"}, - {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3e19ea4ea0bf46179f8a3652ac1426e6dcbaf577ce4b4f65be581e237340420d"}, - {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:bd39c92e4c8f6cbf5f08257d6360123af72af9f4da75a690bef50da77362d25f"}, - {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:b0313e8b923b3814d1c4a524c93dfecea5f39fa95601f6a9b1ac96cd66f89ea0"}, - {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:e861ad82892408487be144906a368ddbe2dc6297074ade2d892341b35c59844a"}, - {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:61014615c1274df8da5991a1e5da85a3ccb00c2d4701ac6f3383afd3ca47ab0a"}, - {file = "propcache-0.3.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:71ebe3fe42656a2328ab08933d420df5f3ab121772eef78f2dc63624157f0ed9"}, - {file = "propcache-0.3.1-cp311-cp311-win32.whl", hash = "sha256:58aa11f4ca8b60113d4b8e32d37e7e78bd8af4d1a5b5cb4979ed856a45e62005"}, - {file = "propcache-0.3.1-cp311-cp311-win_amd64.whl", hash = "sha256:9532ea0b26a401264b1365146c440a6d78269ed41f83f23818d4b79497aeabe7"}, - {file = "propcache-0.3.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:f78eb8422acc93d7b69964012ad7048764bb45a54ba7a39bb9e146c72ea29723"}, - {file = "propcache-0.3.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:89498dd49c2f9a026ee057965cdf8192e5ae070ce7d7a7bd4b66a8e257d0c976"}, - {file = "propcache-0.3.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:09400e98545c998d57d10035ff623266927cb784d13dd2b31fd33b8a5316b85b"}, - {file = "propcache-0.3.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:aa8efd8c5adc5a2c9d3b952815ff8f7710cefdcaf5f2c36d26aff51aeca2f12f"}, - {file = "propcache-0.3.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c2fe5c910f6007e716a06d269608d307b4f36e7babee5f36533722660e8c4a70"}, - {file = "propcache-0.3.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:a0ab8cf8cdd2194f8ff979a43ab43049b1df0b37aa64ab7eca04ac14429baeb7"}, - {file = "propcache-0.3.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:563f9d8c03ad645597b8d010ef4e9eab359faeb11a0a2ac9f7b4bc8c28ebef25"}, - {file = "propcache-0.3.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:fb6e0faf8cb6b4beea5d6ed7b5a578254c6d7df54c36ccd3d8b3eb00d6770277"}, - {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1c5c7ab7f2bb3f573d1cb921993006ba2d39e8621019dffb1c5bc94cdbae81e8"}, - {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:050b571b2e96ec942898f8eb46ea4bfbb19bd5502424747e83badc2d4a99a44e"}, - {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:e1c4d24b804b3a87e9350f79e2371a705a188d292fd310e663483af6ee6718ee"}, - {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:e4fe2a6d5ce975c117a6bb1e8ccda772d1e7029c1cca1acd209f91d30fa72815"}, - {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:feccd282de1f6322f56f6845bf1207a537227812f0a9bf5571df52bb418d79d5"}, - {file = "propcache-0.3.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:ec314cde7314d2dd0510c6787326bbffcbdc317ecee6b7401ce218b3099075a7"}, - {file = "propcache-0.3.1-cp312-cp312-win32.whl", hash = "sha256:7d2d5a0028d920738372630870e7d9644ce437142197f8c827194fca404bf03b"}, - {file = "propcache-0.3.1-cp312-cp312-win_amd64.whl", hash = "sha256:88c423efef9d7a59dae0614eaed718449c09a5ac79a5f224a8b9664d603f04a3"}, - {file = "propcache-0.3.1-py3-none-any.whl", hash = "sha256:9a8ecf38de50a7f518c21568c80f985e776397b902f1ce0b01f799aba1608b40"}, - {file = "propcache-0.3.1.tar.gz", hash = "sha256:40d980c33765359098837527e18eddefc9a24cea5b45e078a7f3bb5b032c6ecf"}, -] - -[[package]] -name = "pycodestyle" -version = "2.13.0" -requires_python = ">=3.9" -summary = "Python style guide checker" -groups = ["dev"] -files = [ - {file = "pycodestyle-2.13.0-py2.py3-none-any.whl", hash = "sha256:35863c5974a271c7a726ed228a14a4f6daf49df369d8c50cd9a6f58a5e143ba9"}, - {file = "pycodestyle-2.13.0.tar.gz", hash = "sha256:c8415bf09abe81d9c7f872502a6eee881fbe85d8763dd5b9924bb0a01d67efae"}, + {file = "propcache-0.4.1-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:60a8fda9644b7dfd5dece8c61d8a85e271cb958075bfc4e01083c148b61a7caf"}, + {file = "propcache-0.4.1-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:c30b53e7e6bda1d547cabb47c825f3843a0a1a42b0496087bb58d8fedf9f41b5"}, + {file = "propcache-0.4.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:6918ecbd897443087a3b7cd978d56546a812517dcaaca51b49526720571fa93e"}, + {file = "propcache-0.4.1-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3d902a36df4e5989763425a8ab9e98cd8ad5c52c823b34ee7ef307fd50582566"}, + {file = "propcache-0.4.1-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:a9695397f85973bb40427dedddf70d8dc4a44b22f1650dd4af9eedf443d45165"}, + {file = "propcache-0.4.1-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:2bb07ffd7eaad486576430c89f9b215f9e4be68c4866a96e97db9e97fead85dc"}, + {file = "propcache-0.4.1-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:fd6f30fdcf9ae2a70abd34da54f18da086160e4d7d9251f81f3da0ff84fc5a48"}, + {file = "propcache-0.4.1-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:fc38cba02d1acba4e2869eef1a57a43dfbd3d49a59bf90dda7444ec2be6a5570"}, + {file = "propcache-0.4.1-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:67fad6162281e80e882fb3ec355398cf72864a54069d060321f6cd0ade95fe85"}, + {file = "propcache-0.4.1-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:f10207adf04d08bec185bae14d9606a1444715bc99180f9331c9c02093e1959e"}, + {file = "propcache-0.4.1-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:e9b0d8d0845bbc4cfcdcbcdbf5086886bc8157aa963c31c777ceff7846c77757"}, + {file = "propcache-0.4.1-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:981333cb2f4c1896a12f4ab92a9cc8f09ea664e9b7dbdc4eff74627af3a11c0f"}, + {file = "propcache-0.4.1-cp311-cp311-win32.whl", hash = "sha256:f1d2f90aeec838a52f1c1a32fe9a619fefd5e411721a9117fbf82aea638fe8a1"}, + {file = "propcache-0.4.1-cp311-cp311-win_amd64.whl", hash = "sha256:364426a62660f3f699949ac8c621aad6977be7126c5807ce48c0aeb8e7333ea6"}, + {file = "propcache-0.4.1-cp311-cp311-win_arm64.whl", hash = "sha256:e53f3a38d3510c11953f3e6a33f205c6d1b001129f972805ca9b42fc308bc239"}, + {file = "propcache-0.4.1-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e153e9cd40cc8945138822807139367f256f89c6810c2634a4f6902b52d3b4e2"}, + {file = "propcache-0.4.1-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:cd547953428f7abb73c5ad82cbb32109566204260d98e41e5dfdc682eb7f8403"}, + {file = "propcache-0.4.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:f048da1b4f243fc44f205dfd320933a951b8d89e0afd4c7cacc762a8b9165207"}, + {file = "propcache-0.4.1-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:ec17c65562a827bba85e3872ead335f95405ea1674860d96483a02f5c698fa72"}, + {file = "propcache-0.4.1-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:405aac25c6394ef275dee4c709be43745d36674b223ba4eb7144bf4d691b7367"}, + {file = "propcache-0.4.1-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:0013cb6f8dde4b2a2f66903b8ba740bdfe378c943c4377a200551ceb27f379e4"}, + {file = "propcache-0.4.1-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:15932ab57837c3368b024473a525e25d316d8353016e7cc0e5ba9eb343fbb1cf"}, + {file = "propcache-0.4.1-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:031dce78b9dc099f4c29785d9cf5577a3faf9ebf74ecbd3c856a7b92768c3df3"}, + {file = "propcache-0.4.1-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:ab08df6c9a035bee56e31af99be621526bd237bea9f32def431c656b29e41778"}, + {file = "propcache-0.4.1-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:4d7af63f9f93fe593afbf104c21b3b15868efb2c21d07d8732c0c4287e66b6a6"}, + {file = "propcache-0.4.1-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:cfc27c945f422e8b5071b6e93169679e4eb5bf73bbcbf1ba3ae3a83d2f78ebd9"}, + {file = "propcache-0.4.1-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:35c3277624a080cc6ec6f847cbbbb5b49affa3598c4535a0a4682a697aaa5c75"}, + {file = "propcache-0.4.1-cp312-cp312-win32.whl", hash = "sha256:671538c2262dadb5ba6395e26c1731e1d52534bfe9ae56d0b5573ce539266aa8"}, + {file = "propcache-0.4.1-cp312-cp312-win_amd64.whl", hash = "sha256:cb2d222e72399fcf5890d1d5cc1060857b9b236adff2792ff48ca2dfd46c81db"}, + {file = "propcache-0.4.1-cp312-cp312-win_arm64.whl", hash = "sha256:204483131fb222bdaaeeea9f9e6c6ed0cac32731f75dfc1d4a567fc1926477c1"}, + {file = "propcache-0.4.1-py3-none-any.whl", hash = "sha256:af2a6052aeb6cf17d3e46ee169099044fd8224cbaf75c76a2ef596e8163e2237"}, + {file = "propcache-0.4.1.tar.gz", hash = "sha256:f48107a8c637e80362555f37ecf49abe20370e557cc4ab374f04ec4423c97c3d"}, ] [[package]] name = "pycparser" -version = "2.22" +version = "2.23" requires_python = ">=3.8" summary = "C parser in Python" groups = ["default"] -marker = "platform_python_implementation != \"PyPy\"" +marker = "implementation_name != \"PyPy\" 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"}, + {file = "pycparser-2.23-py3-none-any.whl", hash = "sha256:e5c6e8d3fbad53479cab09ac03729e0a9faf2bee3db8208a550daf5af81a5934"}, + {file = "pycparser-2.23.tar.gz", hash = "sha256:78816d4f24add8f10a06d6f05b4d424ad9e96cfebf68a4ddc99c65c0720d00c2"}, ] [[package]] name = "pydantic" -version = "2.11.3" +version = "2.12.0" requires_python = ">=3.9" summary = "Data validation using Python type hints" groups = ["default"] dependencies = [ "annotated-types>=0.6.0", - "pydantic-core==2.33.1", - "typing-extensions>=4.12.2", - "typing-inspection>=0.4.0", + "pydantic-core==2.41.1", + "typing-extensions>=4.14.1", + "typing-inspection>=0.4.2", ] files = [ - {file = "pydantic-2.11.3-py3-none-any.whl", hash = "sha256:a082753436a07f9ba1289c6ffa01cd93db3548776088aa917cc43b63f68fa60f"}, - {file = "pydantic-2.11.3.tar.gz", hash = "sha256:7471657138c16adad9322fe3070c0116dd6c3ad8d649300e3cbdfe91f4db4ec3"}, + {file = "pydantic-2.12.0-py3-none-any.whl", hash = "sha256:f6a1da352d42790537e95e83a8bdfb91c7efbae63ffd0b86fa823899e807116f"}, + {file = "pydantic-2.12.0.tar.gz", hash = "sha256:c1a077e6270dbfb37bfd8b498b3981e2bb18f68103720e51fa6c306a5a9af563"}, ] [[package]] name = "pydantic-core" -version = "2.33.1" +version = "2.41.1" requires_python = ">=3.9" summary = "Core functionality for Pydantic validation and serialization" groups = ["default"] dependencies = [ - "typing-extensions!=4.7.0,>=4.6.0", -] -files = [ - {file = "pydantic_core-2.33.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:6e966fc3caaf9f1d96b349b0341c70c8d6573bf1bac7261f7b0ba88f96c56c24"}, - {file = "pydantic_core-2.33.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:bfd0adeee563d59c598ceabddf2c92eec77abcb3f4a391b19aa7366170bd9e30"}, - {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:91815221101ad3c6b507804178a7bb5cb7b2ead9ecd600041669c8d805ebd595"}, - {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:9fea9c1869bb4742d174a57b4700c6dadea951df8b06de40c2fedb4f02931c2e"}, - {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:1d20eb4861329bb2484c021b9d9a977566ab16d84000a57e28061151c62b349a"}, - {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:0fb935c5591573ae3201640579f30128ccc10739b45663f93c06796854405505"}, - {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:c964fd24e6166420d18fb53996d8c9fd6eac9bf5ae3ec3d03015be4414ce497f"}, - {file = "pydantic_core-2.33.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:681d65e9011f7392db5aa002b7423cc442d6a673c635668c227c6c8d0e5a4f77"}, - {file = "pydantic_core-2.33.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:e100c52f7355a48413e2999bfb4e139d2977a904495441b374f3d4fb4a170961"}, - {file = "pydantic_core-2.33.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:048831bd363490be79acdd3232f74a0e9951b11b2b4cc058aeb72b22fdc3abe1"}, - {file = "pydantic_core-2.33.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:bdc84017d28459c00db6f918a7272a5190bec3090058334e43a76afb279eac7c"}, - {file = "pydantic_core-2.33.1-cp311-cp311-win32.whl", hash = "sha256:32cd11c5914d1179df70406427097c7dcde19fddf1418c787540f4b730289896"}, - {file = "pydantic_core-2.33.1-cp311-cp311-win_amd64.whl", hash = "sha256:2ea62419ba8c397e7da28a9170a16219d310d2cf4970dbc65c32faf20d828c83"}, - {file = "pydantic_core-2.33.1-cp311-cp311-win_arm64.whl", hash = "sha256:fc903512177361e868bc1f5b80ac8c8a6e05fcdd574a5fb5ffeac5a9982b9e89"}, - {file = "pydantic_core-2.33.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:1293d7febb995e9d3ec3ea09caf1a26214eec45b0f29f6074abb004723fc1de8"}, - {file = "pydantic_core-2.33.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:99b56acd433386c8f20be5c4000786d1e7ca0523c8eefc995d14d79c7a081498"}, - {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:35a5ec3fa8c2fe6c53e1b2ccc2454398f95d5393ab398478f53e1afbbeb4d939"}, - {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:b172f7b9d2f3abc0efd12e3386f7e48b576ef309544ac3a63e5e9cdd2e24585d"}, - {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:9097b9f17f91eea659b9ec58148c0747ec354a42f7389b9d50701610d86f812e"}, - {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:cc77ec5b7e2118b152b0d886c7514a4653bcb58c6b1d760134a9fab915f777b3"}, - {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:d5e3d15245b08fa4a84cefc6c9222e6f37c98111c8679fbd94aa145f9a0ae23d"}, - {file = "pydantic_core-2.33.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:ef99779001d7ac2e2461d8ab55d3373fe7315caefdbecd8ced75304ae5a6fc6b"}, - {file = "pydantic_core-2.33.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:fc6bf8869e193855e8d91d91f6bf59699a5cdfaa47a404e278e776dd7f168b39"}, - {file = "pydantic_core-2.33.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:b1caa0bc2741b043db7823843e1bde8aaa58a55a58fda06083b0569f8b45693a"}, - {file = "pydantic_core-2.33.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:ec259f62538e8bf364903a7d0d0239447059f9434b284f5536e8402b7dd198db"}, - {file = "pydantic_core-2.33.1-cp312-cp312-win32.whl", hash = "sha256:e14f369c98a7c15772b9da98987f58e2b509a93235582838bd0d1d8c08b68fda"}, - {file = "pydantic_core-2.33.1-cp312-cp312-win_amd64.whl", hash = "sha256:1c607801d85e2e123357b3893f82c97a42856192997b95b4d8325deb1cd0c5f4"}, - {file = "pydantic_core-2.33.1-cp312-cp312-win_arm64.whl", hash = "sha256:8d13f0276806ee722e70a1c93da19748594f19ac4299c7e41237fc791d1861ea"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:3a371dc00282c4b84246509a5ddc808e61b9864aa1eae9ecc92bb1268b82db4a"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:f59295ecc75a1788af8ba92f2e8c6eeaa5a94c22fc4d151e8d9638814f85c8fc"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:08530b8ac922003033f399128505f513e30ca770527cc8bbacf75a84fcc2c74b"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bae370459da6a5466978c0eacf90690cb57ec9d533f8e63e564ef3822bfa04fe"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:e3de2777e3b9f4d603112f78006f4ae0acb936e95f06da6cb1a45fbad6bdb4b5"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:3a64e81e8cba118e108d7126362ea30e021291b7805d47e4896e52c791be2761"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:52928d8c1b6bda03cc6d811e8923dffc87a2d3c8b3bfd2ce16471c7147a24850"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:1b30d92c9412beb5ac6b10a3eb7ef92ccb14e3f2a8d7732e2d739f58b3aa7544"}, - {file = "pydantic_core-2.33.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f995719707e0e29f0f41a8aa3bcea6e761a36c9136104d3189eafb83f5cec5e5"}, - {file = "pydantic_core-2.33.1.tar.gz", hash = "sha256:bcc9c6fdb0ced789245b02b7d6603e17d1563064ddcfc36f046b61c0c05dd9df"}, + "typing-extensions>=4.14.1", +] +files = [ + {file = "pydantic_core-2.41.1-cp311-cp311-macosx_10_12_x86_64.whl", hash = "sha256:4f276a6134fe1fc1daa692642a3eaa2b7b858599c49a7610816388f5e37566a1"}, + {file = "pydantic_core-2.41.1-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:07588570a805296ece009c59d9a679dc08fab72fb337365afb4f3a14cfbfc176"}, + {file = "pydantic_core-2.41.1-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:28527e4b53400cd60ffbd9812ccb2b5135d042129716d71afd7e45bf42b855c0"}, + {file = "pydantic_core-2.41.1-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:46a1c935c9228bad738c8a41de06478770927baedf581d172494ab36a6b96575"}, + {file = "pydantic_core-2.41.1-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:447ddf56e2b7d28d200d3e9eafa936fe40485744b5a824b67039937580b3cb20"}, + {file = "pydantic_core-2.41.1-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:63892ead40c1160ac860b5debcc95c95c5a0035e543a8b5a4eac70dd22e995f4"}, + {file = "pydantic_core-2.41.1-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:f4a9543ca355e6df8fbe9c83e9faab707701e9103ae857ecb40f1c0cf8b0e94d"}, + {file = "pydantic_core-2.41.1-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:f2611bdb694116c31e551ed82e20e39a90bea9b7ad9e54aaf2d045ad621aa7a1"}, + {file = "pydantic_core-2.41.1-cp311-cp311-musllinux_1_1_aarch64.whl", hash = "sha256:fecc130893a9b5f7bfe230be1bb8c61fe66a19db8ab704f808cb25a82aad0bc9"}, + {file = "pydantic_core-2.41.1-cp311-cp311-musllinux_1_1_armv7l.whl", hash = "sha256:1e2df5f8344c99b6ea5219f00fdc8950b8e6f2c422fbc1cc122ec8641fac85a1"}, + {file = "pydantic_core-2.41.1-cp311-cp311-musllinux_1_1_x86_64.whl", hash = "sha256:35291331e9d8ed94c257bab6be1cb3a380b5eee570a2784bffc055e18040a2ea"}, + {file = "pydantic_core-2.41.1-cp311-cp311-win32.whl", hash = "sha256:2876a095292668d753f1a868c4a57c4ac9f6acbd8edda8debe4218d5848cf42f"}, + {file = "pydantic_core-2.41.1-cp311-cp311-win_amd64.whl", hash = "sha256:b92d6c628e9a338846a28dfe3fcdc1a3279388624597898b105e078cdfc59298"}, + {file = "pydantic_core-2.41.1-cp311-cp311-win_arm64.whl", hash = "sha256:7d82ae99409eb69d507a89835488fb657faa03ff9968a9379567b0d2e2e56bc5"}, + {file = "pydantic_core-2.41.1-cp312-cp312-macosx_10_12_x86_64.whl", hash = "sha256:db2f82c0ccbce8f021ad304ce35cbe02aa2f95f215cac388eed542b03b4d5eb4"}, + {file = "pydantic_core-2.41.1-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:47694a31c710ced9205d5f1e7e8af3ca57cbb8a503d98cb9e33e27c97a501601"}, + {file = "pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:93e9decce94daf47baf9e9d392f5f2557e783085f7c5e522011545d9d6858e00"}, + {file = "pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.whl", hash = "sha256:ab0adafdf2b89c8b84f847780a119437a0931eca469f7b44d356f2b426dd9741"}, + {file = "pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:5da98cc81873f39fd56882e1569c4677940fbc12bce6213fad1ead784192d7c8"}, + {file = "pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:209910e88afb01fd0fd403947b809ba8dba0e08a095e1f703294fda0a8fdca51"}, + {file = "pydantic_core-2.41.1-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:365109d1165d78d98e33c5bfd815a9b5d7d070f578caefaabcc5771825b4ecb5"}, + {file = "pydantic_core-2.41.1-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:706abf21e60a2857acdb09502bc853ee5bce732955e7b723b10311114f033115"}, + {file = "pydantic_core-2.41.1-cp312-cp312-musllinux_1_1_aarch64.whl", hash = "sha256:bf0bd5417acf7f6a7ec3b53f2109f587be176cb35f9cf016da87e6017437a72d"}, + {file = "pydantic_core-2.41.1-cp312-cp312-musllinux_1_1_armv7l.whl", hash = "sha256:2e71b1c6ceb9c78424ae9f63a07292fb769fb890a4e7efca5554c47f33a60ea5"}, + {file = "pydantic_core-2.41.1-cp312-cp312-musllinux_1_1_x86_64.whl", hash = "sha256:80745b9770b4a38c25015b517451c817799bfb9d6499b0d13d8227ec941cb513"}, + {file = "pydantic_core-2.41.1-cp312-cp312-win32.whl", hash = "sha256:83b64d70520e7890453f1aa21d66fda44e7b35f1cfea95adf7b4289a51e2b479"}, + {file = "pydantic_core-2.41.1-cp312-cp312-win_amd64.whl", hash = "sha256:377defd66ee2003748ee93c52bcef2d14fde48fe28a0b156f88c3dbf9bc49a50"}, + {file = "pydantic_core-2.41.1-cp312-cp312-win_arm64.whl", hash = "sha256:c95caff279d49c1d6cdfe2996e6c2ad712571d3b9caaa209a404426c326c4bde"}, + {file = "pydantic_core-2.41.1-pp311-pypy311_pp73-macosx_10_12_x86_64.whl", hash = "sha256:af2385d3f98243fb733862f806c5bb9122e5fba05b373e3af40e3c82d711cef1"}, + {file = "pydantic_core-2.41.1-pp311-pypy311_pp73-macosx_11_0_arm64.whl", hash = "sha256:6550617a0c2115be56f90c31a5370261d8ce9dbf051c3ed53b51172dd34da696"}, + {file = "pydantic_core-2.41.1-pp311-pypy311_pp73-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:dc17b6ecf4983d298686014c92ebc955a9f9baf9f57dad4065e7906e7bee6222"}, + {file = "pydantic_core-2.41.1-pp311-pypy311_pp73-manylinux_2_5_i686.manylinux1_i686.whl", hash = "sha256:42ae9352cf211f08b04ea110563d6b1e415878eea5b4c70f6bdb17dca3b932d2"}, + {file = "pydantic_core-2.41.1-pp311-pypy311_pp73-musllinux_1_1_aarch64.whl", hash = "sha256:e82947de92068b0a21681a13dd2102387197092fbe7defcfb8453e0913866506"}, + {file = "pydantic_core-2.41.1-pp311-pypy311_pp73-musllinux_1_1_armv7l.whl", hash = "sha256:e244c37d5471c9acdcd282890c6c4c83747b77238bfa19429b8473586c907656"}, + {file = "pydantic_core-2.41.1-pp311-pypy311_pp73-musllinux_1_1_x86_64.whl", hash = "sha256:1e798b4b304a995110d41ec93653e57975620ccb2842ba9420037985e7d7284e"}, + {file = "pydantic_core-2.41.1-pp311-pypy311_pp73-win_amd64.whl", hash = "sha256:f1fc716c0eb1663c59699b024428ad5ec2bcc6b928527b8fe28de6cb89f47efb"}, + {file = "pydantic_core-2.41.1.tar.gz", hash = "sha256:1ad375859a6d8c356b7704ec0f547a58e82ee80bb41baa811ad710e124bc8f2f"}, ] [[package]] name = "pydantic-settings" -version = "2.9.1" +version = "2.11.0" requires_python = ">=3.9" summary = "Settings management using Pydantic" groups = ["default"] @@ -974,38 +773,8 @@ dependencies = [ "typing-inspection>=0.4.0", ] files = [ - {file = "pydantic_settings-2.9.1-py3-none-any.whl", hash = "sha256:59b4f431b1defb26fe620c71a7d3968a710d719f5f4cdbbdb7926edeb770f6ef"}, - {file = "pydantic_settings-2.9.1.tar.gz", hash = "sha256:c509bf79d27563add44e8446233359004ed85066cd096d8b510f715e6ef5d268"}, -] - -[[package]] -name = "pyflakes" -version = "3.3.2" -requires_python = ">=3.9" -summary = "passive checker of Python programs" -groups = ["dev"] -files = [ - {file = "pyflakes-3.3.2-py2.py3-none-any.whl", hash = "sha256:5039c8339cbb1944045f4ee5466908906180f13cc99cc9949348d10f82a5c32a"}, - {file = "pyflakes-3.3.2.tar.gz", hash = "sha256:6dfd61d87b97fba5dcfaaf781171ac16be16453be6d816147989e7f6e6a9576b"}, -] - -[[package]] -name = "pytest" -version = "8.3.5" -requires_python = ">=3.8" -summary = "pytest: simple powerful testing with Python" -groups = ["dev"] -dependencies = [ - "colorama; sys_platform == \"win32\"", - "exceptiongroup>=1.0.0rc8; python_version < \"3.11\"", - "iniconfig", - "packaging", - "pluggy<2,>=1.5", - "tomli>=1; python_version < \"3.11\"", -] -files = [ - {file = "pytest-8.3.5-py3-none-any.whl", hash = "sha256:c69214aa47deac29fad6c2a4f590b9c4a9fdb16a403176fe154b79c0b4d4d820"}, - {file = "pytest-8.3.5.tar.gz", hash = "sha256:f4efe70cc14e511565ac476b57c279e12a855b11f48f212af1080ef2263d3845"}, + {file = "pydantic_settings-2.11.0-py3-none-any.whl", hash = "sha256:fe2cea3413b9530d10f3a5875adffb17ada5c1e1bab0b2885546d7310415207c"}, + {file = "pydantic_settings-2.11.0.tar.gz", hash = "sha256:d0e87a1c7d33593beb7194adb8470fc426e95ba02af83a0f23474a04c9a08180"}, ] [[package]] @@ -1024,18 +793,18 @@ files = [ [[package]] name = "python-dotenv" -version = "1.1.0" +version = "1.1.1" requires_python = ">=3.9" summary = "Read key-value pairs from a .env file and set them as environment variables" groups = ["default"] files = [ - {file = "python_dotenv-1.1.0-py3-none-any.whl", hash = "sha256:d7c01d9e2293916c18baf562d95698754b0dbbb5e74d457c45d4f6561fb9d55d"}, - {file = "python_dotenv-1.1.0.tar.gz", hash = "sha256:41f90bc6f5f177fb41f53e87666db362025010eb28f60a01c9143bfa33a2b2d5"}, + {file = "python_dotenv-1.1.1-py3-none-any.whl", hash = "sha256:31f23644fe2602f88ff55e1f5c79ba497e01224ee7737937930c448e4d0e24dc"}, + {file = "python_dotenv-1.1.1.tar.gz", hash = "sha256:a8a6399716257f45be6a007360200409fce5cda2661e3dec71d23dc15f6189ab"}, ] [[package]] name = "python-json-logger" -version = "3.3.0" +version = "4.0.0" requires_python = ">=3.8" summary = "JSON Log Formatter for the Python Logging Package" groups = ["default"] @@ -1043,36 +812,36 @@ dependencies = [ "typing-extensions; python_version < \"3.10\"", ] files = [ - {file = "python_json_logger-3.3.0-py3-none-any.whl", hash = "sha256:dd980fae8cffb24c13caf6e158d3d61c0d6d22342f932cb6e9deedab3d35eec7"}, - {file = "python_json_logger-3.3.0.tar.gz", hash = "sha256:12b7e74b17775e7d565129296105bbe3910842d9d0eb083fc83a6a617aa8df84"}, + {file = "python_json_logger-4.0.0-py3-none-any.whl", hash = "sha256:af09c9daf6a813aa4cc7180395f50f2a9e5fa056034c9953aec92e381c5ba1e2"}, + {file = "python_json_logger-4.0.0.tar.gz", hash = "sha256:f58e68eb46e1faed27e0f574a55a0455eecd7b8a5b88b85a784519ba3cff047f"}, ] [[package]] name = "redis" -version = "5.2.1" -requires_python = ">=3.8" +version = "6.4.0" +requires_python = ">=3.9" summary = "Python client for Redis database and key-value store" groups = ["default"] dependencies = [ "async-timeout>=4.0.3; python_full_version < \"3.11.3\"", ] files = [ - {file = "redis-5.2.1-py3-none-any.whl", hash = "sha256:ee7e1056b9aea0f04c6c2ed59452947f34c4940ee025f5dd83e6a6418b6989e4"}, - {file = "redis-5.2.1.tar.gz", hash = "sha256:16f2e22dff21d5125e8481515e386711a34cbec50f0e44413dd7d9c060a54e0f"}, + {file = "redis-6.4.0-py3-none-any.whl", hash = "sha256:f0544fa9604264e9464cdf4814e7d4830f74b165d52f2a330a760a88dd248b7f"}, + {file = "redis-6.4.0.tar.gz", hash = "sha256:b01bc7282b8444e28ec36b261df5375183bb47a07eb9c603f284e89cbc5ef010"}, ] [[package]] name = "s3transfer" -version = "0.11.3" -requires_python = ">=3.8" +version = "0.13.1" +requires_python = ">=3.9" summary = "An Amazon S3 Transfer Manager" groups = ["default"] dependencies = [ - "botocore<2.0a.0,>=1.36.0", + "botocore<2.0a.0,>=1.37.4", ] files = [ - {file = "s3transfer-0.11.3-py3-none-any.whl", hash = "sha256:ca855bdeb885174b5ffa95b9913622459d4ad8e331fc98eb01e6d5eb6a30655d"}, - {file = "s3transfer-0.11.3.tar.gz", hash = "sha256:edae4977e3a122445660c7c114bba949f9d191bae3b34a096f18a1c8c354527a"}, + {file = "s3transfer-0.13.1-py3-none-any.whl", hash = "sha256:a981aa7429be23fe6dfc13e80e4020057cbab622b08c0315288758d67cabc724"}, + {file = "s3transfer-0.13.1.tar.gz", hash = "sha256:c3fdba22ba1bd367922f27ec8032d6a1cf5f10c934fb5d68cf60fd5a23d936cf"}, ] [[package]] @@ -1098,19 +867,224 @@ files = [ ] [[package]] -name = "typing-extensions" -version = "4.13.2" +name = "sqsi" +version = "0.1.9" +requires_python = ">3.10.0" +summary = "Async Iterators for SQS Queues" +groups = ["default"] +dependencies = [ + "aiobotocore>=2.23.1", + "types-aiobotocore[sqs]>=2.23.1", +] +files = [ + {file = "sqsi-0.1.9-py3-none-any.whl", hash = "sha256:88b783dffa8bd7daab6fbeef504b7eb141656af443145d272d8452147e890567"}, + {file = "sqsi-0.1.9.tar.gz", hash = "sha256:3015afac496b9480c1f522722bda223706d39236b5a299853d2ff3c621031e5c"}, +] + +[[package]] +name = "types-aioboto3" +version = "15.2.0" +requires_python = ">=3.8" +summary = "Type annotations for aioboto3 15.2.0 generated with mypy-boto3-builder 8.11.0" +groups = ["default"] +dependencies = [ + "botocore-stubs", + "types-aiobotocore", + "types-s3transfer", + "typing-extensions>=4.1.0; python_version < \"3.12\"", +] +files = [ + {file = "types_aioboto3-15.2.0-py3-none-any.whl", hash = "sha256:8432aa01680fb9263b49780cb0bbff6fe5a42783072bf702ee9450a5d2e8092b"}, + {file = "types_aioboto3-15.2.0.tar.gz", hash = "sha256:bd8f344b9063e5919947d7e4079b610c7bd2d446b55b4ef56d1401f2af3230b0"}, +] + +[[package]] +name = "types-aioboto3" +version = "15.2.0" +extras = ["essential"] +requires_python = ">=3.8" +summary = "Type annotations for aioboto3 15.2.0 generated with mypy-boto3-builder 8.11.0" +groups = ["default"] +dependencies = [ + "types-aioboto3==15.2.0", + "types-aiobotocore-cloudformation<2.25.0,>=2.24.0", + "types-aiobotocore-dynamodb<2.25.0,>=2.24.0", + "types-aiobotocore-ec2<2.25.0,>=2.24.0", + "types-aiobotocore-lambda<2.25.0,>=2.24.0", + "types-aiobotocore-rds<2.25.0,>=2.24.0", + "types-aiobotocore-s3<2.25.0,>=2.24.0", + "types-aiobotocore-sqs<2.25.0,>=2.24.0", +] +files = [ + {file = "types_aioboto3-15.2.0-py3-none-any.whl", hash = "sha256:8432aa01680fb9263b49780cb0bbff6fe5a42783072bf702ee9450a5d2e8092b"}, + {file = "types_aioboto3-15.2.0.tar.gz", hash = "sha256:bd8f344b9063e5919947d7e4079b610c7bd2d446b55b4ef56d1401f2af3230b0"}, +] + +[[package]] +name = "types-aiobotocore" +version = "2.24.3" requires_python = ">=3.8" -summary = "Backported and Experimental Type Hints for Python 3.8+" +summary = "Type annotations for aiobotocore 2.24.3 generated with mypy-boto3-builder 8.11.0" +groups = ["default"] +dependencies = [ + "botocore-stubs", + "typing-extensions>=4.1.0; python_version < \"3.12\"", +] +files = [ + {file = "types_aiobotocore-2.24.3-py3-none-any.whl", hash = "sha256:313250d1dfc8392248a0083eb158f39616fe7e6593ceca7d670ec6da5c02e9a8"}, + {file = "types_aiobotocore-2.24.3.tar.gz", hash = "sha256:b2b43b2e3102c2c4d4c3bca4a7ec97f89856cdde000355512e019e0dbdcd4a36"}, +] + +[[package]] +name = "types-aiobotocore-cloudformation" +version = "2.24.3" +requires_python = ">=3.8" +summary = "Type annotations for aiobotocore CloudFormation 2.24.3 service generated with mypy-boto3-builder 8.11.0" +groups = ["default"] +dependencies = [ + "typing-extensions; python_version < \"3.12\"", +] +files = [ + {file = "types_aiobotocore_cloudformation-2.24.3-py3-none-any.whl", hash = "sha256:be9dfbd57d51343a8d912c377d75bf7550bd6454e5f7ce3d66d4ce59081ea874"}, + {file = "types_aiobotocore_cloudformation-2.24.3.tar.gz", hash = "sha256:15c7523d44b73e69e37d55d61187c316cae2404ab10e7bb812bf11f339e92351"}, +] + +[[package]] +name = "types-aiobotocore-dynamodb" +version = "2.24.3" +requires_python = ">=3.8" +summary = "Type annotations for aiobotocore DynamoDB 2.24.3 service generated with mypy-boto3-builder 8.11.0" +groups = ["default"] +dependencies = [ + "typing-extensions; python_version < \"3.12\"", +] +files = [ + {file = "types_aiobotocore_dynamodb-2.24.3-py3-none-any.whl", hash = "sha256:44441f678325b766d55be6e8aee19f72da8234fb6434904aad9c23efe38075d6"}, + {file = "types_aiobotocore_dynamodb-2.24.3.tar.gz", hash = "sha256:4cd4d3be44f8db6aa47fa3f5c569686349e65249d1d4deef035fbd87014d9523"}, +] + +[[package]] +name = "types-aiobotocore-ec2" +version = "2.24.3" +requires_python = ">=3.8" +summary = "Type annotations for aiobotocore EC2 2.24.3 service generated with mypy-boto3-builder 8.11.0" +groups = ["default"] +dependencies = [ + "typing-extensions; python_version < \"3.12\"", +] +files = [ + {file = "types_aiobotocore_ec2-2.24.3-py3-none-any.whl", hash = "sha256:2dcab835e272640c1d0133db177b8403a239128d929d6bbb218bd09d144c3e0e"}, + {file = "types_aiobotocore_ec2-2.24.3.tar.gz", hash = "sha256:3f5cec201f6042dcbae147041dc6830eba9de42ecbfdf08db9d43ddd733e4669"}, +] + +[[package]] +name = "types-aiobotocore-lambda" +version = "2.24.3" +requires_python = ">=3.8" +summary = "Type annotations for aiobotocore Lambda 2.24.3 service generated with mypy-boto3-builder 8.11.0" +groups = ["default"] +dependencies = [ + "typing-extensions; python_version < \"3.12\"", +] +files = [ + {file = "types_aiobotocore_lambda-2.24.3-py3-none-any.whl", hash = "sha256:42b496b4a6770b811749db400a3ed636cae7c2197944e2a5e44630f902149d31"}, + {file = "types_aiobotocore_lambda-2.24.3.tar.gz", hash = "sha256:588b80da8aaafe5646ad68d219910684214829153d40a835012c79cdba61fb21"}, +] + +[[package]] +name = "types-aiobotocore-rds" +version = "2.24.3" +requires_python = ">=3.8" +summary = "Type annotations for aiobotocore RDS 2.24.3 service generated with mypy-boto3-builder 8.11.0" +groups = ["default"] +dependencies = [ + "typing-extensions; python_version < \"3.12\"", +] +files = [ + {file = "types_aiobotocore_rds-2.24.3-py3-none-any.whl", hash = "sha256:22e30e934f44e98423f87978e77ecc4044d886b9758327b8ce098c3c7aa72d05"}, + {file = "types_aiobotocore_rds-2.24.3.tar.gz", hash = "sha256:d97c7087997c804f8b28946264d61bf74a30eb579b27b5127768725fbaa7dda0"}, +] + +[[package]] +name = "types-aiobotocore-s3" +version = "2.24.3" +requires_python = ">=3.8" +summary = "Type annotations for aiobotocore S3 2.24.3 service generated with mypy-boto3-builder 8.11.0" +groups = ["default"] +dependencies = [ + "typing-extensions; python_version < \"3.12\"", +] +files = [ + {file = "types_aiobotocore_s3-2.24.3-py3-none-any.whl", hash = "sha256:0a00a26e6805fdbe55db5aa8ba273127b740d2106f00abdf6477990527daebe6"}, + {file = "types_aiobotocore_s3-2.24.3.tar.gz", hash = "sha256:77c6ebdb8829f1f93e2efbd486a92e88d92d61477e6e657aeac4df3be8113d58"}, +] + +[[package]] +name = "types-aiobotocore-sqs" +version = "2.24.3" +requires_python = ">=3.8" +summary = "Type annotations for aiobotocore SQS 2.24.3 service generated with mypy-boto3-builder 8.11.0" +groups = ["default"] +dependencies = [ + "typing-extensions; python_version < \"3.12\"", +] +files = [ + {file = "types_aiobotocore_sqs-2.24.3-py3-none-any.whl", hash = "sha256:373317327415df8176790cddf2d28bcc6baa64e51e78b9eb6e70f726fb9f9a05"}, + {file = "types_aiobotocore_sqs-2.24.3.tar.gz", hash = "sha256:d575b5c3ddb05cd978b77218f761a8a6e3fd545455e09a5f4cbcc2530edbb231"}, +] + +[[package]] +name = "types-aiobotocore" +version = "2.24.3" +extras = ["sqs"] +requires_python = ">=3.8" +summary = "Type annotations for aiobotocore 2.24.3 generated with mypy-boto3-builder 8.11.0" +groups = ["default"] +dependencies = [ + "types-aiobotocore-sqs<2.25.0,>=2.24.0", + "types-aiobotocore==2.24.3", +] +files = [ + {file = "types_aiobotocore-2.24.3-py3-none-any.whl", hash = "sha256:313250d1dfc8392248a0083eb158f39616fe7e6593ceca7d670ec6da5c02e9a8"}, + {file = "types_aiobotocore-2.24.3.tar.gz", hash = "sha256:b2b43b2e3102c2c4d4c3bca4a7ec97f89856cdde000355512e019e0dbdcd4a36"}, +] + +[[package]] +name = "types-awscrt" +version = "0.28.1" +requires_python = ">=3.8" +summary = "Type annotations and code completion for awscrt" +groups = ["default"] +files = [ + {file = "types_awscrt-0.28.1-py3-none-any.whl", hash = "sha256:d88f43ef779f90b841ba99badb72fe153077225a4e426ae79e943184827b4443"}, + {file = "types_awscrt-0.28.1.tar.gz", hash = "sha256:66d77ec283e1dc907526a44511a12624118723a396c36d3f3dd9855cb614ce14"}, +] + +[[package]] +name = "types-s3transfer" +version = "0.14.0" +requires_python = ">=3.8" +summary = "Type annotations and code completion for s3transfer" +groups = ["default"] +files = [ + {file = "types_s3transfer-0.14.0-py3-none-any.whl", hash = "sha256:108134854069a38b048e9b710b9b35904d22a9d0f37e4e1889c2e6b58e5b3253"}, + {file = "types_s3transfer-0.14.0.tar.gz", hash = "sha256:17f800a87c7eafab0434e9d87452c809c290ae906c2024c24261c564479e9c95"}, +] + +[[package]] +name = "typing-extensions" +version = "4.15.0" +requires_python = ">=3.9" +summary = "Backported and Experimental Type Hints for Python 3.9+" groups = ["default"] files = [ - {file = "typing_extensions-4.13.2-py3-none-any.whl", hash = "sha256:a439e7c04b49fec3e5d3e2beaa21755cadbbdc391694e28ccdd36ca4a1408f8c"}, - {file = "typing_extensions-4.13.2.tar.gz", hash = "sha256:e6c81219bd689f51865d9e372991c540bda33a0379d5573cddb9a3a23f7caaef"}, + {file = "typing_extensions-4.15.0-py3-none-any.whl", hash = "sha256:f0fa19c6845758ab08074a0cfa8b7aecb71c999ca73d62883bc25cc018c4e548"}, + {file = "typing_extensions-4.15.0.tar.gz", hash = "sha256:0cea48d173cc12fa28ecabc3b837ea3cf6f38c6d1136f85cbaaf598984861466"}, ] [[package]] name = "typing-inspection" -version = "0.4.0" +version = "0.4.2" requires_python = ">=3.9" summary = "Runtime typing introspection tools" groups = ["default"] @@ -1118,20 +1092,20 @@ dependencies = [ "typing-extensions>=4.12.0", ] files = [ - {file = "typing_inspection-0.4.0-py3-none-any.whl", hash = "sha256:50e72559fcd2a6367a19f7a7e610e6afcb9fac940c650290eed893d61386832f"}, - {file = "typing_inspection-0.4.0.tar.gz", hash = "sha256:9765c87de36671694a67904bf2c96e395be9c6439bb6c87b5142569dcdd65122"}, + {file = "typing_inspection-0.4.2-py3-none-any.whl", hash = "sha256:4ed1cacbdc298c220f1bd249ed5287caa16f34d44ef4e9c3d0cbad5b521545e7"}, + {file = "typing_inspection-0.4.2.tar.gz", hash = "sha256:ba561c48a67c5958007083d386c3295464928b01faa735ab8547c5692e87f464"}, ] [[package]] name = "urllib3" -version = "2.4.0" +version = "2.5.0" requires_python = ">=3.9" summary = "HTTP library with thread-safe connection pooling, file post, and more." groups = ["default"] marker = "python_version >= \"3.10\"" files = [ - {file = "urllib3-2.4.0-py3-none-any.whl", hash = "sha256:4e16665048960a0900c702d4a66415956a584919c03361cac9f1df5c5dd7e813"}, - {file = "urllib3-2.4.0.tar.gz", hash = "sha256:414bc6535b787febd7567804cc015fee39daab8ad86268f1310a9250697de466"}, + {file = "urllib3-2.5.0-py3-none-any.whl", hash = "sha256:e6b01673c0fa6a13e374b50871808eb3bf7046c4b125b216f6bf1cc604cff0dc"}, + {file = "urllib3-2.5.0.tar.gz", hash = "sha256:3fc47733c7e419d4bc3f6b3dc2b4f890bb743906a30d56ba4a5bfa4bbff92760"}, ] [[package]] @@ -1169,40 +1143,38 @@ files = [ [[package]] name = "wrapt" -version = "1.17.2" +version = "1.17.3" requires_python = ">=3.8" summary = "Module for decorators, wrappers and monkey patching." groups = ["default"] files = [ - {file = "wrapt-1.17.2-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:ff04ef6eec3eee8a5efef2401495967a916feaa353643defcc03fc74fe213b58"}, - {file = "wrapt-1.17.2-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:4db983e7bca53819efdbd64590ee96c9213894272c776966ca6306b73e4affda"}, - {file = "wrapt-1.17.2-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:9abc77a4ce4c6f2a3168ff34b1da9b0f311a8f1cfd694ec96b0603dff1c79438"}, - {file = "wrapt-1.17.2-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:0b929ac182f5ace000d459c59c2c9c33047e20e935f8e39371fa6e3b85d56f4a"}, - {file = "wrapt-1.17.2-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:f09b286faeff3c750a879d336fb6d8713206fc97af3adc14def0cdd349df6000"}, - {file = "wrapt-1.17.2-cp311-cp311-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:1a7ed2d9d039bd41e889f6fb9364554052ca21ce823580f6a07c4ec245c1f5d6"}, - {file = "wrapt-1.17.2-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:129a150f5c445165ff941fc02ee27df65940fcb8a22a61828b1853c98763a64b"}, - {file = "wrapt-1.17.2-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:1fb5699e4464afe5c7e65fa51d4f99e0b2eadcc176e4aa33600a3df7801d6662"}, - {file = "wrapt-1.17.2-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:9a2bce789a5ea90e51a02dfcc39e31b7f1e662bc3317979aa7e5538e3a034f72"}, - {file = "wrapt-1.17.2-cp311-cp311-win32.whl", hash = "sha256:4afd5814270fdf6380616b321fd31435a462019d834f83c8611a0ce7484c7317"}, - {file = "wrapt-1.17.2-cp311-cp311-win_amd64.whl", hash = "sha256:acc130bc0375999da18e3d19e5a86403667ac0c4042a094fefb7eec8ebac7cf3"}, - {file = "wrapt-1.17.2-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:d5e2439eecc762cd85e7bd37161d4714aa03a33c5ba884e26c81559817ca0925"}, - {file = "wrapt-1.17.2-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:3fc7cb4c1c744f8c05cd5f9438a3caa6ab94ce8344e952d7c45a8ed59dd88392"}, - {file = "wrapt-1.17.2-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:8fdbdb757d5390f7c675e558fd3186d590973244fab0c5fe63d373ade3e99d40"}, - {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:5bb1d0dbf99411f3d871deb6faa9aabb9d4e744d67dcaaa05399af89d847a91d"}, - {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:d18a4865f46b8579d44e4fe1e2bcbc6472ad83d98e22a26c963d46e4c125ef0b"}, - {file = "wrapt-1.17.2-cp312-cp312-manylinux_2_5_x86_64.manylinux1_x86_64.manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bc570b5f14a79734437cb7b0500376b6b791153314986074486e0b0fa8d71d98"}, - {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:6d9187b01bebc3875bac9b087948a2bccefe464a7d8f627cf6e48b1bbae30f82"}, - {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:9e8659775f1adf02eb1e6f109751268e493c73716ca5761f8acb695e52a756ae"}, - {file = "wrapt-1.17.2-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:e8b2816ebef96d83657b56306152a93909a83f23994f4b30ad4573b00bd11bb9"}, - {file = "wrapt-1.17.2-cp312-cp312-win32.whl", hash = "sha256:468090021f391fe0056ad3e807e3d9034e0fd01adcd3bdfba977b6fdf4213ea9"}, - {file = "wrapt-1.17.2-cp312-cp312-win_amd64.whl", hash = "sha256:ec89ed91f2fa8e3f52ae53cd3cf640d6feff92ba90d62236a81e4e563ac0e991"}, - {file = "wrapt-1.17.2-py3-none-any.whl", hash = "sha256:b18f2d1533a71f069c7f82d524a52599053d4c7166e9dd374ae2136b7f40f7c8"}, - {file = "wrapt-1.17.2.tar.gz", hash = "sha256:41388e9d4d1522446fe79d3213196bd9e3b301a336965b9e27ca2788ebd122f3"}, + {file = "wrapt-1.17.3-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:273a736c4645e63ac582c60a56b0acb529ef07f78e08dc6bfadf6a46b19c0da7"}, + {file = "wrapt-1.17.3-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:5531d911795e3f935a9c23eb1c8c03c211661a5060aab167065896bbf62a5f85"}, + {file = "wrapt-1.17.3-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:0610b46293c59a3adbae3dee552b648b984176f8562ee0dba099a56cfbe4df1f"}, + {file = "wrapt-1.17.3-cp311-cp311-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:b32888aad8b6e68f83a8fdccbf3165f5469702a7544472bdf41f582970ed3311"}, + {file = "wrapt-1.17.3-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:8cccf4f81371f257440c88faed6b74f1053eef90807b77e31ca057b2db74edb1"}, + {file = "wrapt-1.17.3-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:d8a210b158a34164de8bb68b0e7780041a903d7b00c87e906fb69928bf7890d5"}, + {file = "wrapt-1.17.3-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:79573c24a46ce11aab457b472efd8d125e5a51da2d1d24387666cd85f54c05b2"}, + {file = "wrapt-1.17.3-cp311-cp311-win32.whl", hash = "sha256:c31eebe420a9a5d2887b13000b043ff6ca27c452a9a22fa71f35f118e8d4bf89"}, + {file = "wrapt-1.17.3-cp311-cp311-win_amd64.whl", hash = "sha256:0b1831115c97f0663cb77aa27d381237e73ad4f721391a9bfb2fe8bc25fa6e77"}, + {file = "wrapt-1.17.3-cp311-cp311-win_arm64.whl", hash = "sha256:5a7b3c1ee8265eb4c8f1b7d29943f195c00673f5ab60c192eba2d4a7eae5f46a"}, + {file = "wrapt-1.17.3-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:ab232e7fdb44cdfbf55fc3afa31bcdb0d8980b9b95c38b6405df2acb672af0e0"}, + {file = "wrapt-1.17.3-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:9baa544e6acc91130e926e8c802a17f3b16fbea0fd441b5a60f5cf2cc5c3deba"}, + {file = "wrapt-1.17.3-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6b538e31eca1a7ea4605e44f81a48aa24c4632a277431a6ed3f328835901f4fd"}, + {file = "wrapt-1.17.3-cp312-cp312-manylinux1_x86_64.manylinux_2_28_x86_64.manylinux_2_5_x86_64.whl", hash = "sha256:042ec3bb8f319c147b1301f2393bc19dba6e176b7da446853406d041c36c7828"}, + {file = "wrapt-1.17.3-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3af60380ba0b7b5aeb329bc4e402acd25bd877e98b3727b0135cb5c2efdaefe9"}, + {file = "wrapt-1.17.3-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:0b02e424deef65c9f7326d8c19220a2c9040c51dc165cddb732f16198c168396"}, + {file = "wrapt-1.17.3-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:74afa28374a3c3a11b3b5e5fca0ae03bef8450d6aa3ab3a1e2c30e3a75d023dc"}, + {file = "wrapt-1.17.3-cp312-cp312-win32.whl", hash = "sha256:4da9f45279fff3543c371d5ababc57a0384f70be244de7759c85a7f989cb4ebe"}, + {file = "wrapt-1.17.3-cp312-cp312-win_amd64.whl", hash = "sha256:e71d5c6ebac14875668a1e90baf2ea0ef5b7ac7918355850c0908ae82bcb297c"}, + {file = "wrapt-1.17.3-cp312-cp312-win_arm64.whl", hash = "sha256:604d076c55e2fdd4c1c03d06dc1a31b95130010517b5019db15365ec4a405fc6"}, + {file = "wrapt-1.17.3-py3-none-any.whl", hash = "sha256:7171ae35d2c33d326ac19dd8facb1e82e5fd04ef8c6c0e394d7af55a55051c22"}, + {file = "wrapt-1.17.3.tar.gz", hash = "sha256:f66eb08feaa410fe4eebd17f2a2c8e2e46d3476e9f8c783daa8e09e0faa666d0"}, ] [[package]] name = "yarl" -version = "1.20.0" +version = "1.22.0" requires_python = ">=3.9" summary = "Yet another URL library" groups = ["default"] @@ -1212,40 +1184,38 @@ dependencies = [ "propcache>=0.2.1", ] files = [ - {file = "yarl-1.20.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:fdb5204d17cb32b2de2d1e21c7461cabfacf17f3645e4b9039f210c5d3378bf3"}, - {file = "yarl-1.20.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:eaddd7804d8e77d67c28d154ae5fab203163bd0998769569861258e525039d2a"}, - {file = "yarl-1.20.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:634b7ba6b4a85cf67e9df7c13a7fb2e44fa37b5d34501038d174a63eaac25ee2"}, - {file = "yarl-1.20.0-cp311-cp311-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:6d409e321e4addf7d97ee84162538c7258e53792eb7c6defd0c33647d754172e"}, - {file = "yarl-1.20.0-cp311-cp311-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:ea52f7328a36960ba3231c6677380fa67811b414798a6e071c7085c57b6d20a9"}, - {file = "yarl-1.20.0-cp311-cp311-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:c8703517b924463994c344dcdf99a2d5ce9eca2b6882bb640aa555fb5efc706a"}, - {file = "yarl-1.20.0-cp311-cp311-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:077989b09ffd2f48fb2d8f6a86c5fef02f63ffe6b1dd4824c76de7bb01e4f2e2"}, - {file = "yarl-1.20.0-cp311-cp311-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:0acfaf1da020253f3533526e8b7dd212838fdc4109959a2c53cafc6db611bff2"}, - {file = "yarl-1.20.0-cp311-cp311-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:b4230ac0b97ec5eeb91d96b324d66060a43fd0d2a9b603e3327ed65f084e41f8"}, - {file = "yarl-1.20.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:0a6a1e6ae21cdd84011c24c78d7a126425148b24d437b5702328e4ba640a8902"}, - {file = "yarl-1.20.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:86de313371ec04dd2531f30bc41a5a1a96f25a02823558ee0f2af0beaa7ca791"}, - {file = "yarl-1.20.0-cp311-cp311-musllinux_1_2_i686.whl", hash = "sha256:dd59c9dd58ae16eaa0f48c3d0cbe6be8ab4dc7247c3ff7db678edecbaf59327f"}, - {file = "yarl-1.20.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:a0bc5e05f457b7c1994cc29e83b58f540b76234ba6b9648a4971ddc7f6aa52da"}, - {file = "yarl-1.20.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:c9471ca18e6aeb0e03276b5e9b27b14a54c052d370a9c0c04a68cefbd1455eb4"}, - {file = "yarl-1.20.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:40ed574b4df723583a26c04b298b283ff171bcc387bc34c2683235e2487a65a5"}, - {file = "yarl-1.20.0-cp311-cp311-win32.whl", hash = "sha256:db243357c6c2bf3cd7e17080034ade668d54ce304d820c2a58514a4e51d0cfd6"}, - {file = "yarl-1.20.0-cp311-cp311-win_amd64.whl", hash = "sha256:8c12cd754d9dbd14204c328915e23b0c361b88f3cffd124129955e60a4fbfcfb"}, - {file = "yarl-1.20.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e06b9f6cdd772f9b665e5ba8161968e11e403774114420737f7884b5bd7bdf6f"}, - {file = "yarl-1.20.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:b9ae2fbe54d859b3ade40290f60fe40e7f969d83d482e84d2c31b9bff03e359e"}, - {file = "yarl-1.20.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:6d12b8945250d80c67688602c891237994d203d42427cb14e36d1a732eda480e"}, - {file = "yarl-1.20.0-cp312-cp312-manylinux_2_17_aarch64.manylinux2014_aarch64.whl", hash = "sha256:087e9731884621b162a3e06dc0d2d626e1542a617f65ba7cc7aeab279d55ad33"}, - {file = "yarl-1.20.0-cp312-cp312-manylinux_2_17_armv7l.manylinux2014_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:69df35468b66c1a6e6556248e6443ef0ec5f11a7a4428cf1f6281f1879220f58"}, - {file = "yarl-1.20.0-cp312-cp312-manylinux_2_17_ppc64le.manylinux2014_ppc64le.whl", hash = "sha256:3b2992fe29002fd0d4cbaea9428b09af9b8686a9024c840b8a2b8f4ea4abc16f"}, - {file = "yarl-1.20.0-cp312-cp312-manylinux_2_17_s390x.manylinux2014_s390x.whl", hash = "sha256:4c903e0b42aab48abfbac668b5a9d7b6938e721a6341751331bcd7553de2dcae"}, - {file = "yarl-1.20.0-cp312-cp312-manylinux_2_17_x86_64.manylinux2014_x86_64.whl", hash = "sha256:bf099e2432131093cc611623e0b0bcc399b8cddd9a91eded8bfb50402ec35018"}, - {file = "yarl-1.20.0-cp312-cp312-manylinux_2_5_i686.manylinux1_i686.manylinux_2_17_i686.manylinux2014_i686.whl", hash = "sha256:8a7f62f5dc70a6c763bec9ebf922be52aa22863d9496a9a30124d65b489ea672"}, - {file = "yarl-1.20.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:54ac15a8b60382b2bcefd9a289ee26dc0920cf59b05368c9b2b72450751c6eb8"}, - {file = "yarl-1.20.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:25b3bc0763a7aca16a0f1b5e8ef0f23829df11fb539a1b70476dcab28bd83da7"}, - {file = "yarl-1.20.0-cp312-cp312-musllinux_1_2_i686.whl", hash = "sha256:b2586e36dc070fc8fad6270f93242124df68b379c3a251af534030a4a33ef594"}, - {file = "yarl-1.20.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:866349da9d8c5290cfefb7fcc47721e94de3f315433613e01b435473be63daa6"}, - {file = "yarl-1.20.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:33bb660b390a0554d41f8ebec5cd4475502d84104b27e9b42f5321c5192bfcd1"}, - {file = "yarl-1.20.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:737e9f171e5a07031cbee5e9180f6ce21a6c599b9d4b2c24d35df20a52fabf4b"}, - {file = "yarl-1.20.0-cp312-cp312-win32.whl", hash = "sha256:839de4c574169b6598d47ad61534e6981979ca2c820ccb77bf70f4311dd2cc64"}, - {file = "yarl-1.20.0-cp312-cp312-win_amd64.whl", hash = "sha256:3d7dbbe44b443b0c4aa0971cb07dcb2c2060e4a9bf8d1301140a33a93c98e18c"}, - {file = "yarl-1.20.0-py3-none-any.whl", hash = "sha256:5d0fe6af927a47a230f31e6004621fd0959eaa915fc62acfafa67ff7229a3124"}, - {file = "yarl-1.20.0.tar.gz", hash = "sha256:686d51e51ee5dfe62dec86e4866ee0e9ed66df700d55c828a615640adc885307"}, + {file = "yarl-1.22.0-cp311-cp311-macosx_10_9_universal2.whl", hash = "sha256:1ab72135b1f2db3fed3997d7e7dc1b80573c67138023852b6efb336a5eae6511"}, + {file = "yarl-1.22.0-cp311-cp311-macosx_10_9_x86_64.whl", hash = "sha256:669930400e375570189492dc8d8341301578e8493aec04aebc20d4717f899dd6"}, + {file = "yarl-1.22.0-cp311-cp311-macosx_11_0_arm64.whl", hash = "sha256:792a2af6d58177ef7c19cbf0097aba92ca1b9cb3ffdd9c7470e156c8f9b5e028"}, + {file = "yarl-1.22.0-cp311-cp311-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:3ea66b1c11c9150f1372f69afb6b8116f2dd7286f38e14ea71a44eee9ec51b9d"}, + {file = "yarl-1.22.0-cp311-cp311-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:3e2daa88dc91870215961e96a039ec73e4937da13cf77ce17f9cad0c18df3503"}, + {file = "yarl-1.22.0-cp311-cp311-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:ba440ae430c00eee41509353628600212112cd5018d5def7e9b05ea7ac34eb65"}, + {file = "yarl-1.22.0-cp311-cp311-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:e6438cc8f23a9c1478633d216b16104a586b9761db62bfacb6425bac0a36679e"}, + {file = "yarl-1.22.0-cp311-cp311-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:4c52a6e78aef5cf47a98ef8e934755abf53953379b7d53e68b15ff4420e6683d"}, + {file = "yarl-1.22.0-cp311-cp311-musllinux_1_2_aarch64.whl", hash = "sha256:3b06bcadaac49c70f4c88af4ffcfbe3dc155aab3163e75777818092478bcbbe7"}, + {file = "yarl-1.22.0-cp311-cp311-musllinux_1_2_armv7l.whl", hash = "sha256:6944b2dc72c4d7f7052683487e3677456050ff77fcf5e6204e98caf785ad1967"}, + {file = "yarl-1.22.0-cp311-cp311-musllinux_1_2_ppc64le.whl", hash = "sha256:d5372ca1df0f91a86b047d1277c2aaf1edb32d78bbcefffc81b40ffd18f027ed"}, + {file = "yarl-1.22.0-cp311-cp311-musllinux_1_2_s390x.whl", hash = "sha256:51af598701f5299012b8416486b40fceef8c26fc87dc6d7d1f6fc30609ea0aa6"}, + {file = "yarl-1.22.0-cp311-cp311-musllinux_1_2_x86_64.whl", hash = "sha256:b266bd01fedeffeeac01a79ae181719ff848a5a13ce10075adbefc8f1daee70e"}, + {file = "yarl-1.22.0-cp311-cp311-win32.whl", hash = "sha256:a9b1ba5610a4e20f655258d5a1fdc7ebe3d837bb0e45b581398b99eb98b1f5ca"}, + {file = "yarl-1.22.0-cp311-cp311-win_amd64.whl", hash = "sha256:078278b9b0b11568937d9509b589ee83ef98ed6d561dfe2020e24a9fd08eaa2b"}, + {file = "yarl-1.22.0-cp311-cp311-win_arm64.whl", hash = "sha256:b6a6f620cfe13ccec221fa312139135166e47ae169f8253f72a0abc0dae94376"}, + {file = "yarl-1.22.0-cp312-cp312-macosx_10_13_universal2.whl", hash = "sha256:e340382d1afa5d32b892b3ff062436d592ec3d692aeea3bef3a5cfe11bbf8c6f"}, + {file = "yarl-1.22.0-cp312-cp312-macosx_10_13_x86_64.whl", hash = "sha256:f1e09112a2c31ffe8d80be1b0988fa6a18c5d5cad92a9ffbb1c04c91bfe52ad2"}, + {file = "yarl-1.22.0-cp312-cp312-macosx_11_0_arm64.whl", hash = "sha256:939fe60db294c786f6b7c2d2e121576628468f65453d86b0fe36cb52f987bd74"}, + {file = "yarl-1.22.0-cp312-cp312-manylinux2014_aarch64.manylinux_2_17_aarch64.manylinux_2_28_aarch64.whl", hash = "sha256:e1651bf8e0398574646744c1885a41198eba53dc8a9312b954073f845c90a8df"}, + {file = "yarl-1.22.0-cp312-cp312-manylinux2014_armv7l.manylinux_2_17_armv7l.manylinux_2_31_armv7l.whl", hash = "sha256:b8a0588521a26bf92a57a1705b77b8b59044cdceccac7151bd8d229e66b8dedb"}, + {file = "yarl-1.22.0-cp312-cp312-manylinux2014_ppc64le.manylinux_2_17_ppc64le.manylinux_2_28_ppc64le.whl", hash = "sha256:42188e6a615c1a75bcaa6e150c3fe8f3e8680471a6b10150c5f7e83f47cc34d2"}, + {file = "yarl-1.22.0-cp312-cp312-manylinux2014_s390x.manylinux_2_17_s390x.manylinux_2_28_s390x.whl", hash = "sha256:f6d2cb59377d99718913ad9a151030d6f83ef420a2b8f521d94609ecc106ee82"}, + {file = "yarl-1.22.0-cp312-cp312-manylinux2014_x86_64.manylinux_2_17_x86_64.manylinux_2_28_x86_64.whl", hash = "sha256:50678a3b71c751d58d7908edc96d332af328839eea883bb554a43f539101277a"}, + {file = "yarl-1.22.0-cp312-cp312-musllinux_1_2_aarch64.whl", hash = "sha256:1e8fbaa7cec507aa24ea27a01456e8dd4b6fab829059b69844bd348f2d467124"}, + {file = "yarl-1.22.0-cp312-cp312-musllinux_1_2_armv7l.whl", hash = "sha256:433885ab5431bc3d3d4f2f9bd15bfa1614c522b0f1405d62c4f926ccd69d04fa"}, + {file = "yarl-1.22.0-cp312-cp312-musllinux_1_2_ppc64le.whl", hash = "sha256:b790b39c7e9a4192dc2e201a282109ed2985a1ddbd5ac08dc56d0e121400a8f7"}, + {file = "yarl-1.22.0-cp312-cp312-musllinux_1_2_s390x.whl", hash = "sha256:31f0b53913220599446872d757257be5898019c85e7971599065bc55065dc99d"}, + {file = "yarl-1.22.0-cp312-cp312-musllinux_1_2_x86_64.whl", hash = "sha256:a49370e8f711daec68d09b821a34e1167792ee2d24d405cbc2387be4f158b520"}, + {file = "yarl-1.22.0-cp312-cp312-win32.whl", hash = "sha256:70dfd4f241c04bd9239d53b17f11e6ab672b9f1420364af63e8531198e3f5fe8"}, + {file = "yarl-1.22.0-cp312-cp312-win_amd64.whl", hash = "sha256:8884d8b332a5e9b88e23f60bb166890009429391864c685e17bd73a9eda9105c"}, + {file = "yarl-1.22.0-cp312-cp312-win_arm64.whl", hash = "sha256:ea70f61a47f3cc93bdf8b2f368ed359ef02a01ca6393916bc8ff877427181e74"}, + {file = "yarl-1.22.0-py3-none-any.whl", hash = "sha256:1380560bdba02b6b6c90de54133c81c9f2a453dee9912fe58c1dcced1edb7cff"}, + {file = "yarl-1.22.0.tar.gz", hash = "sha256:bebf8557577d4401ba8bd9ff33906f1376c877aa78d1fe216ad01b4d6745af71"}, ] diff --git a/pyproject.toml b/pyproject.toml index 7eea032..e74e315 100644 --- a/pyproject.toml +++ b/pyproject.toml @@ -20,18 +20,18 @@ classifiers = [ ] dependencies = [ - "aiohttp>=3.11.11", - "jinja2>=3.1.5", - "aiohttp-jinja2>=1.6", "aioboto3>=14.1.0", "pydantic-settings>=2.7.1", "python-json-logger>=3.2.1", "redis>=5.2.1", - "aio-statsd>=0.2.9", "httpx>=0.28.1", "websockets>=13.0", "atproto>=0.0.59", "aiorwlock>=1.5.0", + "sqsi>=0.1.9", + "types-aioboto3[essential]>=15.1.0", + "aiobotocore>=2.24.0", + "prometheus-client>=0.21.0", ] readme = "README.md" diff --git a/src/social/graze/jetstream_turbo/app/__main__.py b/src/social/graze/jetstream_turbo/app/__main__.py index 1f8f3af..a45b77f 100644 --- a/src/social/graze/jetstream_turbo/app/__main__.py +++ b/src/social/graze/jetstream_turbo/app/__main__.py @@ -1,28 +1,40 @@ -import os -from aiohttp import web -import logging from logging.config import dictConfig import argparse +import asyncio import json +import logging +import os + +from social.graze.jetstream_turbo.app.turbocharger import start_turbo_charger +from social.graze.jetstream_turbo.app.config import Settings +from social.graze.jetstream_turbo.app.metrics import start_metrics_server def configure_logging(): + """ + Configures logging. + """ logging_config_file = os.getenv("LOGGING_CONFIG_FILE", "") if len(logging_config_file) > 0: - with open(logging_config_file) as fl: + with open(logging_config_file, encoding="utf-8") as fl: dictConfig(json.load(fl)) return - logging.basicConfig() - logging.getLogger().setLevel(logging.INFO) + logging.basicConfig( + level=logging.INFO, + format='%(asctime)s - %(name)s - %(levelname)s - %(message)s' + ) + logging.getLogger("httpx").setLevel(logging.WARNING) + +async def start(): + """ + Parse arguments and start turbocharger. + """ -def main(): configure_logging() - from social.graze.jetstream_turbo.app.turbocharger import start_turbo_charger - parser = argparse.ArgumentParser(prog="turbocharger") parser.add_argument( "--modulo", @@ -37,14 +49,22 @@ def main(): help="Shard to test against", ) args = parser.parse_args() - web.run_app( - start_turbo_charger( - None, - modulo=args.modulo, - shard=args.shard, - ) + + # Start Prometheus metrics server + settings = Settings() + start_metrics_server(settings.metrics_port) + + await start_turbo_charger( + settings, + modulo=args.modulo, + shard=args.shard, ) +def main(): + """ + The entrypoint for the program, called if this module is invoked and also in `pyproject.toml`. + """ + asyncio.run(start()) if __name__ == "__main__": main() diff --git a/src/social/graze/jetstream_turbo/app/bluesky_api.py b/src/social/graze/jetstream_turbo/app/bluesky_api.py index 55c48df..701c684 100644 --- a/src/social/graze/jetstream_turbo/app/bluesky_api.py +++ b/src/social/graze/jetstream_turbo/app/bluesky_api.py @@ -1,12 +1,10 @@ import asyncio -import random from typing import List, Dict, TypeVar, Callable, Awaitable from atproto import AsyncClient, models from atproto_client.exceptions import ( BadRequestError, RequestException, - InvokeTimeoutError, ) T = TypeVar("T") @@ -47,14 +45,6 @@ async def load_sessions(cls, session_strings: List[str]) -> List["BlueskyAPI"]: bads.append(ss) return apis - async def _login_client(self, client: AsyncClient, session_string: str): - """Logs a given AsyncClient in with a particular session string.""" - try: - await client.login(session_string=session_string) - await client.user_timeline() - except (BadRequestError, RequestException, ValueError) as e: - raise RuntimeError(f"Failed to login with session string: {e}") - async def _chunked_map( self, items: List[T], diff --git a/src/social/graze/jetstream_turbo/app/client.py b/src/social/graze/jetstream_turbo/app/client.py index 993d29d..2c7d79f 100644 --- a/src/social/graze/jetstream_turbo/app/client.py +++ b/src/social/graze/jetstream_turbo/app/client.py @@ -1,25 +1,73 @@ import asyncio import json +import logging import websockets +import websockets.exceptions +logger = logging.getLogger(__name__) class JetstreamClient: """ Subscribes to a Bluesky jetstream (firehose) and yields parsed messages. """ - def __init__(self, endpoint: str, wanted_collections: str = "app.bsky.feed.post"): + def __init__( + self, + endpoint: str, + wanted_collections: str = "app.bsky.feed.post", + max_retries: int = 5, + retry_window: float = 300 + ): self.endpoint = endpoint self.wanted_collections = wanted_collections + self.max_retries = max_retries + self.retry_window = retry_window - def jetstream_url(self): - return f"wss://{self.endpoint}/subscribe?wantedCollections={self.wanted_collections}" + def jetstream_url(self, time_us: int | None = None): + url = f"wss://{self.endpoint}/subscribe?wantedCollections={self.wanted_collections}" + if time_us: + url += f"&cursor={time_us}" + return url async def run_stream(self): - async with websockets.connect(self.jetstream_url()) as ws: - async for message in ws: - try: - data = json.loads(message) - yield data - except (json.JSONDecodeError, KeyError): - continue + """ Run a Jetstream iterator. """ + + retry_times: list[float] = [] + time_us: int | None = None + + while True: + try: + async with websockets.connect(self.jetstream_url(time_us)) as ws: + async for message in ws: + try: + message = json.loads(message) + try: + time_us = int(message.get("time_us")) + except (TypeError, ValueError, AttributeError): + pass + yield message + except (json.JSONDecodeError, KeyError): + continue + except websockets.exceptions.ConnectionClosedError as e: + logger.error("Exception when reading from jetstream: %s", e, exc_info=True) + + now = asyncio.get_event_loop().time() + retry_times = [t for t in retry_times if now - t < self.retry_window] + retry_times.append(now) + if len(retry_times) > self.max_retries: + logger.error( + "Ending `run_stream()` iterator due to hitting max retries (%d) in window (%.1f s).", + self.max_retries, + self.retry_window, + ) + + logger.error( + "Continuing processing (%d/%d retries in the last %.1f s).", + len(retry_times), + self.max_retries, + self.retry_window, + ) + continue + + # If we're not terminating due to a known exception, break and die. + break diff --git a/src/social/graze/jetstream_turbo/app/config.py b/src/social/graze/jetstream_turbo/app/config.py index 46ca7bb..7bbcc1c 100644 --- a/src/social/graze/jetstream_turbo/app/config.py +++ b/src/social/graze/jetstream_turbo/app/config.py @@ -1,28 +1,36 @@ import os -import asyncio -from typing import Annotated, Final, List +from typing import List, Optional import logging -from aio_statsd import TelegrafStatsdClient -from pydantic import ( - field_validator, - PostgresDsn, - RedisDsn, -) -import base64 -from pydantic_settings import BaseSettings, NoDecode -from aiohttp import web -from cryptography.fernet import Fernet -from aiohttp import ClientSession -from redis import asyncio as redis +from pydantic_settings import BaseSettings logger = logging.getLogger(__name__) class Settings(BaseSettings): + """ Settings for the app. """ + graze_api_base_url: str = "https://api.graze.social" - stream_name: str = os.getenv("STREAM_NAME") - turbo_credential_secret: str = os.getenv("TURBO_CREDENTIAL_SECRET") + stream_name: Optional[str] = os.getenv("STREAM_NAME") + turbo_credential_secret: Optional[str] = os.getenv("TURBO_CREDENTIAL_SECRET") + + s3_bucket: Optional[str] = os.getenv("S3_BUCKET") + s3_region: Optional[str] = os.getenv("S3_REGION") + + input_mode: Optional[str] = ( + "sqs" if os.getenv("INPUT_MODE", "").lower() == "sqs" else "websocket" + ) + + input_queue_url: Optional[str] = os.getenv("INPUT_QUEUE_URL") + + output_to_s3: Optional[bool] = bool(os.getenv("OUTPUT_TO_S3")) + output_to_sqs: Optional[bool] = bool(os.getenv("OUTPUT_TO_SQS")) + output_to_redis: Optional[bool] = bool(os.getenv("OUTPUT_TO_REDIS")) + + output_queue_url: Optional[str] = os.getenv("OUTPUT_QUEUE_URL") + media_output_queue_url: Optional[str] = os.getenv("MEDIA_OUTPUT_QUEUE_URL") + + redis_url: Optional[str] = os.getenv("REDIS_URL") jetstream_hosts: List[str] = [ "jetstream1.us-east.bsky.network", @@ -31,26 +39,5 @@ class Settings(BaseSettings): "jetstream2.us-west.bsky.network", ] db_dir: str = "jetstream-messages" - s3_bucket: str = "graze-turbo-01" - s3_region: str = "us-east-1" - debug: bool = False - - http_port: int = 5100 - - external_hostname: str = "localhost:5100" - - redis_dsn: RedisDsn = RedisDsn("redis://valkey:6379/1?decode_responses=True") - worker_id: str = "worker" - - statsd_host: str = "telegraf" - statsd_port: int = 8125 - statsd_prefix: str = "aip" - -SettingsAppKey: Final = web.AppKey("settings", Settings) -SessionAppKey: Final = web.AppKey("http_session", ClientSession) -RedisPoolAppKey: Final = web.AppKey("redis_pool", redis.ConnectionPool) -RedisClientAppKey: Final = web.AppKey("redis_client", redis.Redis) -TelegrafStatsdClientAppKey: Final = web.AppKey( - "telegraf_statsd_client", TelegrafStatsdClient -) + metrics_port: int = int(os.getenv("METRICS_PORT", "8000")) diff --git a/src/social/graze/jetstream_turbo/app/egress.py b/src/social/graze/jetstream_turbo/app/egress.py index 0ed52b4..b9c2c54 100644 --- a/src/social/graze/jetstream_turbo/app/egress.py +++ b/src/social/graze/jetstream_turbo/app/egress.py @@ -5,11 +5,12 @@ import os import zipfile import logging -import aioboto3 -from datetime import datetime, timedelta +from datetime import datetime, timedelta, UTC from typing import Any, List, Dict, Optional + +import aioboto3 import redis.asyncio as redis -from social.graze.jetstream_turbo.app.remote_storage import upload_file_to_s3 +from types_aiobotocore_s3 import S3Client logger = logging.getLogger(__name__) @@ -19,16 +20,12 @@ class Egress: Handles persisting records to SQLite + S3, and pushes to Redis Stream with trimming. """ - REDIS_CLIENT: Optional[redis.Redis] = None - S3_CLIENT: Any = None - ROTATION_MINUTES = 1 - def __init__( self, db_dir: str = "data_store", s3_bucket: str = "graze-turbo-01", - s3_region: str = "us-east-1", - stream_name: str = "hydrated_jetstream", + s3_region: Optional[str] = "us-east-1", + stream_name: Optional[str] = "hydrated_jetstream", trim_maxlen: Optional[int] = 100, ): self.db_dir = db_dir @@ -43,12 +40,41 @@ def __init__( self.db_start_time: Optional[datetime] = None self.current_db_path: Optional[str] = None + self.session: aioboto3.Session = None # type: ignore + self.s3_client: S3Client = None # type: ignore + self.redis_client: Optional[redis.Redis] = None + self.rotation_minutes = 1 + self._writer_lock = asyncio.Lock() + async def __aenter__(self): + # Initialize our S3 client + self.session = aioboto3.Session() + self.s3_client = await self.session.client("s3", region_name=self.s3_region).__aenter__() + await self.s3_client.head_bucket(Bucket=self.s3_bucket) + + # Initialize Redis + if not (url := os.getenv("REDIS_URL")): + raise RuntimeError("REDIS_URL not set") + self.redis_client = redis.from_url(url) + await self.redis_client.ping() + logger.info("Connected to Redis at %s", url) + + return self + + async def __aexit__(self, exc_type, exc, tb): + if self.s3_client: + await self.s3_client.__aexit__(exc_type, exc, tb) + self.s3_client = None # type: ignore + + if self.redis_client: + await self.redis_client.aclose() + self.redis_client = None + async def _create_new_db(self, rotate_old_db_path: Optional[str] = None): if rotate_old_db_path: asyncio.create_task(self._compress_and_ship_old_db(rotate_old_db_path)) - timestamp = datetime.utcnow().strftime("%Y%m%d_%H%M%S") + timestamp = datetime.now(UTC).strftime("%Y%m%d_%H%M%S") self.current_db_path = os.path.join(self.db_dir, f"jetstream_{timestamp}.db") self.conn = sqlite3.connect(self.current_db_path, check_same_thread=False) self.conn.execute( @@ -67,19 +93,18 @@ async def _create_new_db(self, rotate_old_db_path: Optional[str] = None): f"CREATE INDEX IF NOT EXISTS idx_records_{idx} ON records({idx});" ) self.conn.commit() - self.db_start_time = datetime.utcnow() + self.db_start_time = datetime.now(UTC) async def _compress_and_ship_old_db(self, old_db_path: str): if not os.path.exists(old_db_path): - logger.warning(f"Old DB not found at {old_db_path}, skipping upload.") + logger.warning("Old DB not found at %s, skipping upload.", old_db_path) return # Build zip path zip_path = old_db_path + ".zip" try: with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zf: zf.write(old_db_path, arcname=Path(old_db_path).name) - await self._init_s3_client() - await Egress.S3_CLIENT.upload_file( + await self.s3_client.upload_file( zip_path, self.s3_bucket, Path(zip_path).name ) logger.info( @@ -95,11 +120,8 @@ async def _compress_and_ship_old_db(self, old_db_path: str): logger.info("Deleted local files %s and %s", old_db_path, zip_path) except OSError as rm_err: logger.warning("Failed to delete old DB or zip: %s", rm_err) - except Exception as e: + except Exception as e: # pylint: disable=broad-exception-caught logger.error("Failed to zip/upload %s: %s", old_db_path, e) - if Egress.S3_CLIENT: - await Egress.S3_CLIENT.close() - Egress.S3_CLIENT = None def _parse_time_us(self, time_us: Any) -> Optional[int]: if time_us is None: @@ -109,30 +131,15 @@ def _parse_time_us(self, time_us: Any) -> Optional[int]: except (ValueError, TypeError): return None - async def _init_s3_client(self): - if Egress.S3_CLIENT is None: - session = aioboto3.Session() - Egress.S3_CLIENT = await session.client( - "s3", region_name=self.s3_region - ).__aenter__() - await Egress.S3_CLIENT.head_bucket(Bucket=self.s3_bucket) - - async def _init_redis_client(self): - if Egress.REDIS_CLIENT is None: - url = os.getenv("REDIS_URL") - if not url: - raise RuntimeError("REDIS_URL not set") - client = redis.from_url(url) - await client.ping() - Egress.REDIS_CLIENT = client - logger.info("Connected to Redis at %s", url) - async def push_batch_to_stream(self, batch: List[Dict[str, Any]]): - if not batch: + """ + Push a batch of posts to a Redis stream. + """ + + if not batch or not self.redis_client or not self.stream_name: return - await self._init_redis_client() - client = Egress.REDIS_CLIENT - pipe = client.pipeline() + + pipe = self.redis_client.pipeline() for item in batch: pipe.xadd(self.stream_name, {"data": json.dumps(item)}) if self.trim_maxlen is not None: @@ -141,20 +148,29 @@ async def push_batch_to_stream(self, batch: List[Dict[str, Any]]): await pipe.execute() async def store_records(self, enriched_records: List[Dict[str, Any]]): + """ + Store records in SQLite to be uploaded. + """ + if not enriched_records: return + async with self._writer_lock: if self.conn is None: await self._create_new_db() + assert self.conn is not None + if ( self.db_start_time - and datetime.utcnow() - self.db_start_time - >= timedelta(minutes=self.ROTATION_MINUTES) + and datetime.now(UTC) - self.db_start_time + >= timedelta(minutes=self.rotation_minutes) ): old = self.current_db_path self.conn.close() self.conn = None await self._create_new_db(rotate_old_db_path=old) + assert self.conn is not None + rows = [ ( r.get("at_uri", ""), @@ -172,10 +188,13 @@ async def store_records(self, enriched_records: List[Dict[str, Any]]): ) self.conn.commit() cur.close() + # Trimmed stream push await self.push_batch_to_stream(enriched_records) async def close(self): + """ Close the SQLite connection if it is still open. """ + async with self._writer_lock: if self.conn: self.conn.close() diff --git a/src/social/graze/jetstream_turbo/app/egress/__init__.py b/src/social/graze/jetstream_turbo/app/egress/__init__.py new file mode 100644 index 0000000..0903ece --- /dev/null +++ b/src/social/graze/jetstream_turbo/app/egress/__init__.py @@ -0,0 +1,5 @@ +from social.graze.jetstream_turbo.app.egress.base import EgressBase +from social.graze.jetstream_turbo.app.egress.s3_egress import S3Egress +from social.graze.jetstream_turbo.app.egress.sqs_egress import SQSEgress +from social.graze.jetstream_turbo.app.egress.redis_egress import RedisEgress +from social.graze.jetstream_turbo.app.egress.multiple_egress import MultipleEgress diff --git a/src/social/graze/jetstream_turbo/app/egress/base.py b/src/social/graze/jetstream_turbo/app/egress/base.py new file mode 100644 index 0000000..2888343 --- /dev/null +++ b/src/social/graze/jetstream_turbo/app/egress/base.py @@ -0,0 +1,22 @@ +from abc import ABC, abstractmethod +from typing import Any, Dict, List + + +class EgressBase (ABC): + """ + A base class for methods of egress from this application. + """ + + async def __aenter__(self): + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + pass + + @abstractmethod + async def store_records(self, enriched_records: List[Dict[str, Any]]): + """ + A method to store records in whatever means of egress. + """ + + raise NotImplementedError() \ No newline at end of file diff --git a/src/social/graze/jetstream_turbo/app/egress/multiple_egress.py b/src/social/graze/jetstream_turbo/app/egress/multiple_egress.py new file mode 100644 index 0000000..66e8573 --- /dev/null +++ b/src/social/graze/jetstream_turbo/app/egress/multiple_egress.py @@ -0,0 +1,44 @@ +import asyncio +import contextlib +import logging +from typing import Any, Dict, List +from social.graze.jetstream_turbo.app.egress.base import EgressBase + + +logger = logging.getLogger(__name__) + +class MultipleEgress (EgressBase): + """ + Handles sending egress to multiple places. + """ + + def __init__(self, *methods: EgressBase): + self._exit_stack = contextlib.AsyncExitStack() + self._methods: List[EgressBase] = list(methods) + if len(self._methods) == 0: + logger.warning("No egress methods configured.") + + async def __aenter__(self): + await self._exit_stack.__aenter__() + + for method in self._methods: + await self._exit_stack.enter_async_context(method) + + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + await self._exit_stack.__aexit__(exc_type, exc_val, exc_tb) + + async def store_records(self, enriched_records: List[Dict[str, Any]]): + """ + A method to store records in whatever means of egress. + """ + + results = await asyncio.gather( + *(method.store_records(enriched_records) for method in self._methods), + return_exceptions=True, + ) + + for result in results: + if isinstance(result, Exception): + logger.error("Exception in egress: %s", result, exc_info=True) diff --git a/src/social/graze/jetstream_turbo/app/egress/redis_egress.py b/src/social/graze/jetstream_turbo/app/egress/redis_egress.py new file mode 100644 index 0000000..9809d16 --- /dev/null +++ b/src/social/graze/jetstream_turbo/app/egress/redis_egress.py @@ -0,0 +1,45 @@ +import json +from typing import Any, Dict, List, Optional + +import redis.asyncio as redis + +from social.graze.jetstream_turbo.app.egress.base import EgressBase + + +class RedisEgress (EgressBase): + """ + Output turbostream-enriched results to a Redis stream. + """ + + def __init__(self, redis_url: str, stream_name: str, trim_maxlen: Optional[int] = None): + self.redis_url = redis_url + self.stream_name = stream_name + self.trim_maxlen = trim_maxlen + + self._redis_client: redis.Redis = None # type: ignore + + async def __aenter__(self): + self._redis_client = await redis.from_url(self.redis_url).__aenter__() + await self._redis_client.ping() + + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + if self._redis_client: + await self._redis_client.__aexit__(exc_type, exc_val, exc_tb) + self._redis_client = None # type: ignore + + async def store_records(self, enriched_records: List[Dict[str, Any]]): + """ + Output results to a Redis queue. + """ + + async with self._redis_client.pipeline() as pipe: + + for item in enriched_records: + pipe.xadd(self.stream_name, { "data": json.dumps(item) }) + + if self.trim_maxlen is not None: + pipe.xtrim(self.stream_name, maxlen=self.trim_maxlen, approximate=True) + + await pipe.execute() diff --git a/src/social/graze/jetstream_turbo/app/egress/s3_egress.py b/src/social/graze/jetstream_turbo/app/egress/s3_egress.py new file mode 100644 index 0000000..20a5ff6 --- /dev/null +++ b/src/social/graze/jetstream_turbo/app/egress/s3_egress.py @@ -0,0 +1,164 @@ +import asyncio +import json +import os +import sqlite3 +import logging +import zipfile +from datetime import datetime, timedelta, UTC +from pathlib import Path +from typing import Any, Dict, List, Optional + +import aioboto3 +from types_aiobotocore_s3 import S3Client + +from social.graze.jetstream_turbo.app.egress.base import EgressBase + +logger = logging.getLogger(__name__) + + +class S3Egress (EgressBase): + """ + Handles egress to S3 by persisting records to a SQLite database and pushing them every so + often. + """ + + def __init__( + self, + db_dir: str = "data_store", + s3_bucket: str = "graze-turbo-01", + s3_region: Optional[str] = "us-east-1", + stream_name: str = "hydrated_jetstream", + trim_maxlen: Optional[int] = 100, + ): + self.db_dir = db_dir + os.makedirs(db_dir, exist_ok=True) + + self.s3_bucket = s3_bucket + self.s3_region = s3_region + self.stream_name = stream_name + self.trim_maxlen = trim_maxlen + + self.conn: Optional[sqlite3.Connection] = None + self.db_start_time: Optional[datetime] = None + self.current_db_path: Optional[str] = None + + self.session: aioboto3.Session = None # type: ignore + self.s3_client: S3Client = None # type: ignore + self.rotation_minutes = 1 + + self._writer_lock = asyncio.Lock() + + async def __aenter__(self): + # Initialize our S3 client + self.session = aioboto3.Session() + self.s3_client = await self.session.client("s3", region_name=self.s3_region).__aenter__() + await self.s3_client.head_bucket(Bucket=self.s3_bucket) + + return self + + async def __aexit__(self, exc_type, exc, tb): + if self.s3_client: + await self.s3_client.__aexit__(exc_type, exc, tb) + self.s3_client = None # type: ignore + + async def _create_new_db(self, rotate_old_db_path: Optional[str] = None): + if rotate_old_db_path: + asyncio.create_task(self._compress_and_ship_old_db(rotate_old_db_path)) + timestamp = datetime.now(UTC).strftime("%Y%m%d_%H%M%S") + self.current_db_path = os.path.join(self.db_dir, f"jetstream_{timestamp}.db") + self.conn = sqlite3.connect(self.current_db_path, check_same_thread=False) + self.conn.execute( + """ + CREATE TABLE IF NOT EXISTS records ( + id INTEGER PRIMARY KEY AUTOINCREMENT, + at_uri TEXT CHECK(LENGTH(at_uri) <= 300), + did TEXT CHECK(LENGTH(did) <= 100), + time_us INTEGER, + message TEXT CHECK(json_valid(message)), + message_metadata TEXT CHECK(json_valid(message_metadata)) + )""" + ) + for idx in ("at_uri", "did", "time_us"): + self.conn.execute( + f"CREATE INDEX IF NOT EXISTS idx_records_{idx} ON records({idx});" + ) + self.conn.commit() + self.db_start_time = datetime.now(UTC) + + async def _compress_and_ship_old_db(self, old_db_path: str): + if not os.path.exists(old_db_path): + logger.warning("Old DB not found at %s, skipping upload.", old_db_path) + return + # Build zip path + zip_path = old_db_path + ".zip" + try: + with zipfile.ZipFile(zip_path, "w", zipfile.ZIP_DEFLATED) as zf: + zf.write(old_db_path, arcname=Path(old_db_path).name) + await self.s3_client.upload_file( + zip_path, self.s3_bucket, Path(zip_path).name + ) + logger.info( + "Zipped & shipped %s to s3://%s/%s", + old_db_path, + self.s3_bucket, + Path(zip_path).name, + ) + # --- CLEANUP: delete both the raw DB and its ZIP --- + try: + os.remove(old_db_path) + os.remove(zip_path) + logger.info("Deleted local files %s and %s", old_db_path, zip_path) + except OSError as rm_err: + logger.warning("Failed to delete old DB or zip: %s", rm_err) + except Exception as e: + logger.error("Failed to zip/upload %s: %s", old_db_path, e) + + def _parse_time_us(self, time_us: Any) -> Optional[int]: + if time_us is None: + return None + try: + return int(time_us) + except (ValueError, TypeError): + return None + + async def store_records(self, enriched_records: List[Dict[str, Any]]): + """ + Store records in SQLite to be uploaded. + """ + + if not enriched_records: + return + + async with self._writer_lock: + if self.conn is None: + await self._create_new_db() + assert self.conn is not None + + if ( + self.db_start_time + and datetime.now(UTC) - self.db_start_time + >= timedelta(minutes=self.rotation_minutes) + ): + old = self.current_db_path + self.conn.close() + self.conn = None + await self._create_new_db(rotate_old_db_path=old) + assert self.conn is not None + + rows = [ + ( + r.get("at_uri", ""), + r.get("did", ""), + self._parse_time_us(r.get("time_us")), + json.dumps(r.get("message", {})), + json.dumps(r.get("hydrated_metadata", {})), + ) + for r in enriched_records + ] + cur = self.conn.cursor() + cur.executemany( + "INSERT INTO records(at_uri,did,time_us,message,message_metadata) VALUES(?,?,?,?,?)", + rows, + ) + self.conn.commit() + cur.close() diff --git a/src/social/graze/jetstream_turbo/app/egress/sqs_egress.py b/src/social/graze/jetstream_turbo/app/egress/sqs_egress.py new file mode 100644 index 0000000..c78aa00 --- /dev/null +++ b/src/social/graze/jetstream_turbo/app/egress/sqs_egress.py @@ -0,0 +1,67 @@ +import asyncio +import logging +import json +from typing import Any, Dict, Iterable, List + +from aiobotocore.session import AioSession +from types_aiobotocore_sqs import SQSClient + +from social.graze.jetstream_turbo.app.egress.base import EgressBase +from social.graze.jetstream_turbo.app.utility import chunks +from social.graze.jetstream_turbo.content_extractor import ContentExtractor + +logger = logging.getLogger(__name__) + + +class SQSEgress (EgressBase): + """ + Output turbostream-enriched results to SQS. + """ + + def __init__(self, queue_url: str, media_queue_url: str | None = None): + self.queue_url = queue_url + self.media_queue_url = media_queue_url + + self._session = AioSession() + self._sqs_client: SQSClient = None # type: ignore + self._content_extractor = ContentExtractor() + + async def __aenter__(self): + self._sqs_client = await self._session.create_client("sqs").__aenter__() + + return self + + async def __aexit__(self, exc_type, exc_val, exc_tb): + if self._sqs_client: + await self._sqs_client.__aexit__(exc_type, exc_val, exc_tb) + + async def store_records(self, enriched_records: List[Dict[str, Any]]): + """ + Store records in SQS. + """ + + if self.media_queue_url: + split_records = [(self._has_media(r), r) for r in enriched_records] + await asyncio.gather(*[ + self._send_to_queue(self.media_queue_url, (r for m, r in split_records if m)), + self._send_to_queue(self.queue_url, (r for m, r in split_records if not m)) + ]) + else: + await self._send_to_queue(self.queue_url, enriched_records) + + async def _send_to_queue(self, queue_url: str, records: Iterable[Dict[str, Any]]): + for chunk in chunks(records, 10): + await self._sqs_client.send_message_batch( + QueueUrl=queue_url, + Entries=[ + { + "Id": str(index), + "MessageBody": json.dumps(message) + } + for index, message in enumerate(chunk) + ] + ) + + def _has_media(self, record: Dict[str, Any]): + """ Determine if a record has images or videos in it. """ + return bool(self._content_extractor.extract_videos(record)) diff --git a/src/social/graze/jetstream_turbo/app/graze_api.py b/src/social/graze/jetstream_turbo/app/graze_api.py index c41da33..080d205 100644 --- a/src/social/graze/jetstream_turbo/app/graze_api.py +++ b/src/social/graze/jetstream_turbo/app/graze_api.py @@ -10,6 +10,10 @@ class GrazeAPI: @staticmethod async def fetch_session_strings(settings: Settings) -> List[str]: + """ + Fetch the Bluesky account session strings that we are going to use to do turbo enrichment. + """ + url = f"{settings.graze_api_base_url.rstrip('/')}/app/api/v1/turbo-tokens/credentials?credential_secret={settings.turbo_credential_secret}" async with httpx.AsyncClient() as client: response = await client.get(url, timeout=10.0) diff --git a/src/social/graze/jetstream_turbo/app/hydration.py b/src/social/graze/jetstream_turbo/app/hydration.py index 048b5ee..31d3d6c 100644 --- a/src/social/graze/jetstream_turbo/app/hydration.py +++ b/src/social/graze/jetstream_turbo/app/hydration.py @@ -1,10 +1,10 @@ import asyncio import random -import time -from typing import List, Dict, Any, Tuple, Set -import aiorwlock +from typing import List, Dict, Any, Set from collections import OrderedDict +import aiorwlock + from social.graze.jetstream_turbo.app.bluesky_api import BlueskyAPI @@ -250,5 +250,8 @@ async def fetch_missing_posts(): "message": rec, # the entire raw record "hydrated_metadata": hydrated_metadata, } + if overrides := rec.get("override_algorithms"): + enriched_obj["override_algorithms"] = overrides + enriched_list.append(enriched_obj) return enriched_list diff --git a/src/social/graze/jetstream_turbo/app/metrics.py b/src/social/graze/jetstream_turbo/app/metrics.py new file mode 100644 index 0000000..1e33390 --- /dev/null +++ b/src/social/graze/jetstream_turbo/app/metrics.py @@ -0,0 +1,36 @@ +""" +Prometheus metrics for jetstream-turbo. +""" +import logging +from prometheus_client import Counter, Histogram, disable_created_metrics, start_http_server + +disable_created_metrics() + +logger = logging.getLogger(__name__) + +# Metrics +posts_processed = Counter( + 'jetstream_turbo:posts_processed', + 'Total number of posts processed by the turbocharger' +) + +batch_processing_time = Histogram( + 'jetstream_turbo:batch_time', + 'Time (seconds) taken to process a batch of posts', + buckets=(0.1, 0.5, 1.0, 2.5, 5.0, 10.0, 30.0, 60.0, 120.0, float('inf')) +) + + +def start_metrics_server(port: int = 8000): + """ + Start the Prometheus metrics HTTP server. + + Args: + port: Port to expose metrics on (default: 8000) + """ + try: + start_http_server(port) + logger.info("Prometheus metrics server started on port %d", port) + except Exception as e: + logger.error("Failed to start metrics server: %s", e) + raise diff --git a/src/social/graze/jetstream_turbo/app/remote_storage.py b/src/social/graze/jetstream_turbo/app/remote_storage.py deleted file mode 100644 index e7a50e1..0000000 --- a/src/social/graze/jetstream_turbo/app/remote_storage.py +++ /dev/null @@ -1,22 +0,0 @@ -import os -import asyncio -import aioboto3 -import logging - -logger = logging.getLogger(__name__) - - -async def upload_file_to_s3( - file_path: str, bucket: str, key: str, region_name: str = "us-east-1" -): - """ - Upload the given file to S3 using aioboto3. - :param file_path: path to the local file to upload. - :param bucket: S3 bucket name. - :param key: S3 object key. - :param region_name: AWS region, default 'us-east-1'. - """ - session = aioboto3.Session() - async with session.client("s3", region_name=region_name) as s3: - await s3.upload_file(file_path, bucket, key) - logger.info(f"Uploaded {file_path} to s3://{bucket}/{key}") diff --git a/src/social/graze/jetstream_turbo/app/turbocharger.py b/src/social/graze/jetstream_turbo/app/turbocharger.py index 97a2442..730c3d6 100644 --- a/src/social/graze/jetstream_turbo/app/turbocharger.py +++ b/src/social/graze/jetstream_turbo/app/turbocharger.py @@ -1,15 +1,22 @@ -import json import random import asyncio +import json import logging -from typing import AsyncGenerator, List, Optional +import time +from typing import Any, Iterable, List, Optional + +import sqsi from social.graze.jetstream_turbo.app.client import JetstreamClient from social.graze.jetstream_turbo.app.hydration import Hydration -from social.graze.jetstream_turbo.app.egress import Egress +from social.graze.jetstream_turbo.app.egress import ( + EgressBase, MultipleEgress, RedisEgress, S3Egress, SQSEgress +) from social.graze.jetstream_turbo.app.config import Settings from social.graze.jetstream_turbo.app.graze_api import GrazeAPI from social.graze.jetstream_turbo.app.bluesky_api import BlueskyAPI +from social.graze.jetstream_turbo.app.utility import ConfigurationException +from social.graze.jetstream_turbo.app.metrics import posts_processed, batch_processing_time logger = logging.getLogger(__name__) @@ -24,12 +31,12 @@ class TurboCharger: def __init__( self, - storage_instance: Egress, + egress: EgressBase, session_strings: List[str], endpoint: str, *, - modulo: int = None, - shard: int = None, + modulo: Optional[int] = None, + shard: Optional[int] = None, ): self.session_strings = session_strings self.endpoint = endpoint @@ -39,13 +46,19 @@ def __init__( self.client = JetstreamClient(endpoint) self.buffer = [] self.semaphore = asyncio.Semaphore(100) - self.storage = storage_instance + self.egress = egress + + self.bluesky_clients: List[BlueskyAPI] = [] async def load_clients(self): + """ + Load Bluesky API clients from sessions. + """ + random.shuffle(self.session_strings) self.bluesky_clients = await BlueskyAPI.load_sessions(self.session_strings) - async def run(self) -> AsyncGenerator[List[dict], None]: + async def run_from_jetstream(self): """ Reads raw messages from the jetstream, buffers them in groups of 100, hydrates them in parallel, and yields the enriched records. @@ -56,21 +69,42 @@ async def run(self) -> AsyncGenerator[List[dict], None]: ): self.buffer.append(record) if len(self.buffer) >= BATCH_SIZE: - await self._process_batch() + batch = self.buffer[:BATCH_SIZE] + self.buffer = self.buffer[BATCH_SIZE:] + await self._process_batch(batch) # Process any leftover records if the stream ends if self.buffer: - await self._process_batch() + batch = self.buffer[:BATCH_SIZE] + self.buffer = self.buffer[BATCH_SIZE:] + await self._process_batch(batch) + + async def run_from_sqs(self, queue_url: str): + """ + Read raw messages from SQS, buffers them in groups of `BATCH_SIZE`, hydrates them in + parallel, and yields the enriched results. + """ - async def _process_batch(self): + async with sqsi.QueueIterator( + queue_url, + buffer_size=10, + wait_time=1, + deletion_mode="handle", + transformer=json.loads, + transformer_exceptions="skip-delete", + transformer_exception_logger=logger.info, + ) as queue: + async for chunk in queue.chunks(size=BATCH_SIZE, timeout=1): # type: ignore + await self._process_batch(message for message, _ in chunk) + await queue.mark_complete(*(handle for _, handle in chunk)) + + async def _process_batch(self, batch: Iterable[Any]): """ Processes a batch of up to 100 records by hydrating them in bulk. """ - batch = self.buffer[:BATCH_SIZE] - self.buffer = self.buffer[BATCH_SIZE:] await self.semaphore.acquire() - asyncio.create_task(self._hydrate_and_release(batch, self.semaphore)) + asyncio.create_task(self._hydrate_and_release(list(batch), self.semaphore)) async def _hydrate_and_release( self, records: List[dict], semaphore: asyncio.Semaphore @@ -78,12 +112,15 @@ async def _hydrate_and_release( """ Hydrates a batch of records and emits the enriched data. """ + start_time = time.time() try: - logger.debug(f"Got {len(records)} records, enriching...") + # logger.info("Got %d records, enriching...", len(records)) enriched = await Hydration.hydrate_bulk(records, self.bluesky_clients) - logger.debug(f"Enriched {len(records)} records, storing...") - await self.storage.store_records(enriched) - logger.debug(f"Stored {len(records)} records.") + # logger.info("Enriched %d records, storing...", len(records)) + await self.egress.store_records(enriched) + logger.info("Stored %d records.", len(records)) + posts_processed.inc(len(records)) + batch_processing_time.observe(time.time() - start_time) finally: semaphore.release() @@ -91,31 +128,71 @@ async def _hydrate_and_release( async def start_turbo_charger( settings: Optional[Settings] = None, *, - modulo: int = None, - shard: int = None, + modulo: Optional[int] = None, + shard: Optional[int] = None, ): """ Starts the TurboCharger with configured settings. """ if settings is None: - settings = Settings() # type: ignore - - storage_instance = Egress( - db_dir=settings.db_dir, - s3_bucket=settings.s3_bucket, - s3_region=settings.s3_region, - stream_name=settings.stream_name, - ) - - session_strings = await GrazeAPI.fetch_session_strings(settings) - - turbo_charger = TurboCharger( - storage_instance=storage_instance, - session_strings=session_strings, - endpoint=random.choice(settings.jetstream_hosts), - modulo=modulo, - shard=shard, - ) - - await turbo_charger.load_clients() - await turbo_charger.run() + settings = Settings() + + async with MultipleEgress(*get_egress_methods(settings)) as egress: + session_strings = await GrazeAPI.fetch_session_strings(settings) + + turbo_charger = TurboCharger( + egress=egress, + session_strings=session_strings, + endpoint=random.choice(settings.jetstream_hosts), + modulo=modulo, + shard=shard, + ) + + await turbo_charger.load_clients() + if settings.input_mode == "sqs": + if not settings.input_queue_url: + raise ConfigurationException("Mode is SQS but `INPUT_QUEUE_URL` is not set.") + logger.info("Input from SQS queue: %s", settings.input_queue_url) + await turbo_charger.run_from_sqs(settings.input_queue_url) + else: + logger.info("Input from Websocket") + await turbo_charger.run_from_jetstream() + +def get_egress_methods(settings: Settings): + """ Get an iterator of egress methods. """ + + if settings.output_to_s3: + if not settings.s3_bucket: + raise ConfigurationException("settings.s3_bucket must be set to egress to S3.") + + logger.info("Egress to S3 bucket %s", settings.s3_bucket) + + yield S3Egress( + db_dir=settings.db_dir, + s3_bucket=settings.s3_bucket, + s3_region=settings.s3_region, + ) + + if settings.output_to_sqs: + if not settings.output_queue_url: + raise ConfigurationException("settings.output_queue_url must be set to egress to SQS.") + + logger.info("Egress to SQS queue %s", settings.output_queue_url) + + yield SQSEgress( + queue_url=settings.output_queue_url, + media_queue_url=settings.media_output_queue_url, + ) + + if settings.output_to_redis: + if not settings.redis_url: + raise ConfigurationException("settings.redis_url must be set to egress to Redis.") + if not settings.stream_name: + raise ConfigurationException("settings.stream_name must be set to egress to Redis.") + + logger.info("Egress to Redis stream %s", settings.stream_name) + + yield RedisEgress( + redis_url=settings.redis_url, + stream_name=settings.stream_name, + ) diff --git a/src/social/graze/jetstream_turbo/app/utility.py b/src/social/graze/jetstream_turbo/app/utility.py new file mode 100644 index 0000000..d0f518f --- /dev/null +++ b/src/social/graze/jetstream_turbo/app/utility.py @@ -0,0 +1,15 @@ +import itertools +from typing import Iterable, TypeVar + + +T = TypeVar('T') + +def chunks(iterable: Iterable[T], size: int): + """ Break an array into chunks of size `size` or smaller.""" + + iterator = iter(iterable) + while chunk := list(itertools.islice(iterator, size)): + yield chunk + +class ConfigurationException (Exception): + """ A class for an exception with the application configuration. """ \ No newline at end of file diff --git a/src/social/graze/jetstream_turbo/content_extractor.py b/src/social/graze/jetstream_turbo/content_extractor.py new file mode 100644 index 0000000..bfc5bbd --- /dev/null +++ b/src/social/graze/jetstream_turbo/content_extractor.py @@ -0,0 +1,295 @@ +from typing import Dict, List, Any, Optional +import logging + +logger = logging.getLogger(__name__) + + +class ContentExtractor: + """Extracts text, images, and videos from Bluesky posts.""" + + # Define text field paths to extract + TEXT_PATHS = [ + "message.commit.record.text", + "message.commit.record.embed.external.description", + "message.commit.record.embed.external.title", + "message.commit.record.embed.external.thumb.alt", + # Note: Removed "message.commit.record.embed.images[].alt" to avoid concatenation + # Alt texts are now handled individually with each image + "message.commit.record.embed.record.value.text", + "message.commit.record.embed.video.alt", + "message.hydrated_metadata.user.description", + "message.hydrated_metadata.parent_post.record.text", + "message.hydrated_metadata.parent_post.record.embed.external.description", + "message.hydrated_metadata.parent_post.record.embed.external.title", + # Removed array notation for alt texts + "message.hydrated_metadata.reply_post.record.text", + "message.hydrated_metadata.quote_post.record.text", + "message.hydrated_metadata.quote_post.record.embed.video.alt", + "message.hydrated_metadata.quote_post.value.text", + "message.hydrated_metadata.quote_post.embed.record.value.text" + ] + + def extract_text_fields(self, post: Dict[str, Any]) -> Dict[str, str]: + """ + Extract all text fields from a post. + + Returns: + Dict mapping field path to text content + """ + texts = {} + + for path in self.TEXT_PATHS: + try: + value = self._extract_by_path(post, path) + if value: + texts[path] = value + except Exception as e: + logger.debug(f"Error extracting {path}: {e}") + + return texts + + def extract_images(self, post: Dict[str, Any]) -> List[Dict[str, Any]]: + """ + Extract all images from a post. + + Returns: + List of dicts with 'url' and 'data' keys + """ + images = [] + did = post.get("did") + + # Direct image embed + if self._get_nested(post, "message.commit.record.embed.$type") == "app.bsky.embed.images": + embed_images = self._get_nested(post, "message.commit.record.embed.images") or [] + images.extend(self._process_image_list(embed_images, did)) + + # External embed with thumbnail + if (self._get_nested(post, "message.commit.record.embed.$type") == "app.bsky.embed.external" and + self._get_nested(post, "message.commit.record.embed.external.thumb")): + thumb = self._get_nested(post, "message.commit.record.embed.external.thumb") + if thumb: + processed = self._process_image(thumb, is_thumb=True, did=did) + if processed: + images.append(processed) + + # Record with media (images) - IMPORTANT: handle galleries + if self._get_nested(post, "message.commit.record.embed.$type") == "app.bsky.embed.recordWithMedia": + # Check the media type + media = self._get_nested(post, "message.commit.record.embed.media") + if media and media.get("$type") == "app.bsky.embed.images": + media_images = media.get("images") or [] + images.extend(self._process_image_list(media_images, did)) + + # Images in hydrated metadata + for path in [ + "message.hydrated_metadata.parent_post.embed.images", + "message.hydrated_metadata.parent_post.embed.media.images", + "message.hydrated_metadata.quote_post.embed.images", + "message.hydrated_metadata.quote_post.embed.media.images", + "message.hydrated_metadata.parent_post.record.embed.images", + "message.hydrated_metadata.reply_post.embed.images", + "message.hydrated_metadata.reply_post.embed.media.images" + ]: + embed_images = self._get_nested(post, path) + if embed_images: + # Try to get DID from the parent/quote/reply post + parent_did = None + if "parent_post" in path: + parent_did = self._get_nested(post, "message.hydrated_metadata.parent_post.did") + elif "quote_post" in path: + parent_did = self._get_nested(post, "message.hydrated_metadata.quote_post.did") + elif "reply_post" in path: + parent_did = self._get_nested(post, "message.hydrated_metadata.reply_post.did") + images.extend(self._process_image_list(embed_images, parent_did or did)) + + return images + + def extract_videos(self, post: Dict[str, Any]) -> List[Dict[str, Any]]: + """ + Extract all videos from a post. + + Returns: + List of dicts with 'url', 'data', and 'needs_did_resolution' keys + """ + videos = [] + did = post.get("did") + + # Direct video embed + if self._get_nested(post, "message.commit.record.embed.$type") == "app.bsky.embed.video": + video = self._get_nested(post, "message.commit.record.embed.video") + if video: + processed = self._process_video(video, did) + if processed: + videos.append(processed) + + # Record with media (video) + if (self._get_nested(post, "message.commit.record.embed.$type") == "app.bsky.embed.recordWithMedia" and + self._get_nested(post, "message.commit.record.embed.media.$type") == "app.bsky.embed.video"): + video = self._get_nested(post, "message.commit.record.embed.media.video") + if video: + processed = self._process_video(video, did) + if processed: + videos.append(processed) + + # External media that might be video + if (self._get_nested(post, "message.commit.record.embed.$type") == "app.bsky.embed.recordWithMedia" and + self._get_nested(post, "message.commit.record.embed.media.$type") == "app.bsky.embed.external"): + external = self._get_nested(post, "message.commit.record.embed.media.external") + if external: + uri = external.get("uri", "") + # Check for common video extensions + video_extensions = ['.mp4', '.webm', '.avi', '.mov', '.mkv', '.m4v'] + if any(uri.lower().endswith(ext) for ext in video_extensions): + videos.append({ + "url": uri, + "data": None, + "alt": external.get("alt", ""), + "needs_did_resolution": False + }) + + # Videos in hydrated metadata + for path in [ + "message.hydrated_metadata.parent_post.embed.video", + "message.hydrated_metadata.quote_post.embed.video" + ]: + video = self._get_nested(post, path) + if video: + # Try to get DID from the parent/quote post + parent_did = None + if "parent_post" in path: + parent_did = self._get_nested(post, "message.hydrated_metadata.parent_post.did") + elif "quote_post" in path: + parent_did = self._get_nested(post, "message.hydrated_metadata.quote_post.did") + + processed = self._process_video(video, parent_did or did) + if processed: + videos.append(processed) + + return videos + + def extract_embedding_text(self, post: Dict[str, Any]) -> str: + """ + Extract the text field used for text embeddings from a post. + + Returns: + Dict mapping field path to text content + """ + + return post.get("message", {}).get("commit", {}).get("record", {}).get("text", "") + + def _extract_by_path(self, data: Dict[str, Any], path: str) -> Optional[str]: + """Extract value by dot-separated path, handling arrays.""" + if "[]" in path: + # Handle array notation + parts = path.split("[]") + base_path = parts[0] + remaining_path = parts[1].lstrip(".") if len(parts) > 1 else None + + array_value = self._get_nested(data, base_path) + if not isinstance(array_value, list): + return None + + # Collect values from array + values = [] + for item in array_value: + if remaining_path: + val = self._get_nested(item, remaining_path) + else: + val = item + + if val and isinstance(val, str): + values.append(val) + + return " ".join(values) if values else None + else: + # Simple path + value = self._get_nested(data, path) + return value if isinstance(value, str) else None + + def _get_nested(self, data: Dict[str, Any], path: str) -> Any: + """Get nested value from dict using dot notation.""" + current = data + for part in path.split("."): + if not isinstance(current, dict): + return None + current = current.get(part) + if current is None: + return None + return current + + def _process_image_list(self, images: List[Dict[str, Any]], did: str | None = None) -> List[Dict[str, Any]]: + """Process a list of image objects.""" + processed = [] + for img in images: + result = self._process_image(img, did=did) + if result: + processed.append(result) + return processed + + def _process_image(self, image: Dict[str, Any], is_thumb: bool = False, did: str | None = None) -> Optional[Dict[str, Any]]: + """Process a single image object.""" + if is_thumb: + # External thumbnail + url = image.get("uri") or image.get("url") + if url: + return { + "url": url, + "data": None, # Will be fetched if needed + "alt": image.get("alt", "") + } + else: + # Regular image embed + image_info = image.get("image") or {} + cid = image_info.get("ref", {}).get("$link") + + if cid and did: + # Construct CDN URL for Bluesky image + url = f"https://cdn.bsky.app/img/feed_thumbnail/plain/{did}/{cid}@jpeg" + return { + "url": url, + "data": None, # Will be fetched if needed + "alt": image.get("alt", ""), + "aspect_ratio": image.get("aspectRatio") + } + else: + # Fallback to other URL formats + url = image_info.get("uri") or image_info.get("url") + if url: + return { + "url": url, + "data": None, # Will be fetched if needed + "alt": image.get("alt", ""), + "aspect_ratio": image.get("aspectRatio") + } + + return None + + def _process_video(self, video: Dict[str, Any], did: str | None = None) -> Optional[Dict[str, Any]]: + """Process a video object.""" + video_info = video.get("video") or video + cid = video_info.get("ref", {}).get("$link") + + if cid and did: + # Video needs DID resolution to get PDS endpoint + return { + "url": None, # Will be constructed after DID resolution + "cid": cid, + "did": did, + "data": None, + "alt": video.get("alt", ""), + "aspect_ratio": video.get("aspectRatio"), + "needs_did_resolution": True + } + else: + # Try direct URL + url = video_info.get("uri") or video_info.get("url") + if url: + return { + "url": url, + "data": None, + "alt": video.get("alt", ""), + "aspect_ratio": video.get("aspectRatio"), + "needs_did_resolution": False + } + + return None